Animal.txt

January 12, 2021

Today’s task is from a beginning programmer, who starts with an input file called animal.txt:

There once was a Dog

Wednesday he ate Apples 
Thursday he ate Apples
Friday he ate Apples
Saturday he ate carrots

There once was a Bear

Tuesday he ate carrots
Wednesday he ate carrots
Thursday he ate chicken

He wants to create this output:

Food: Apples Animals who ate it: 1
=======
Dog

Food: Carrots Animals who ate it: 2
========
Bear
Dog

Food: Chicken Animals who ate it: 1
========
Bear

He gave a complicated awk solution that didn’t work; it produced duplicate lines of output in those cases
where the same animal ate the same food on multiple days.

Your task is to write a program to produces the desired transformation form input to output. When
you are finished, you are welcome to read or run a suggested solution, or to post your own solution or
discuss the exercise in the comments below.

Pages: 1 2

5 Responses to “Animal.txt”

  1. Zack said

    A cute little exercise. I hope it’s not counted as cheating if I tackle it using Julia (1.5.2): https://pastebin.com/UDbyNBhQ

    I really had no idea that bears ate carrots!

  2. Daniel said

    Here’s a solution in Python.

    import sys
    from collections import defaultdict
    
    lookup = defaultdict(set)  # maps foods to a set of animals
    
    with open(sys.argv[1]) as f:
        for line in f.readlines():
            line = line.strip()
            if line.startswith('The'):  # 'The' identifies 'There once ...'
                animal = line[17:].capitalize()  # len('There once was a ') == 17
            elif line:
                food = line[line.index(' ') + 8:].capitalize()  # len(' he ate ') == 8
                lookup[food].add(animal)
    
    for idx, (food, animals) in enumerate(lookup.items()):
        print(f'Food: {food} Animals who ate it: {len(animals)}')
        print('=======')
        for animal in animals:
            print(animal)
        if idx + 1 < len(lookup):
            print()
    

    Example usage:

    $ python3.9 animal.py animal.txt
    Food: Apples Animals who ate it: 1
    =======
    Dog
    
    Food: Carrots Animals who ate it: 2
    =======
    Bear
    Dog
    
    Food: Chicken Animals who ate it: 1
    =======
    Bear
    
  3. esilence said

    Python

    import re

    inFile = open(‘animal.txt’)

    dt = dict()
    l = set()
    f = ”
    for line in inFile:
    if re.match(“There once was a”, line):
    if f:
    dt[f] = l
    f = line.split()[-1].capitalize()
    l = set()
    elif re.search(“he ate”, line):
    s = line.split()[-1].capitalize()
    l.add(s)
    dt[f] = l

    dtr = dict() #reverse dict
    for k, v in dt.items():
    for iv in v:
    if iv in dtr:
    dtr[iv].add(k)
    else:
    dtr[iv] = set([k])

    for val in dtr:
    print(‘\nFood: {} Animals who ate it: {}’.format(val, len(dtr[val])))
    print(‘=======’)
    for i in dtr[val]:
    print(i)

  4. Globules said

    Here’s an AWK version. The food names are capitalized, and the output sorted, to match the example.

    /There once was a/ {
        animal = $5
    }
    
    /he ate/ {
        foods[$4][animal] = 1
    }
    
    END {
        PROCINFO["sorted_in"] = "@val_str_asc"
        for (f in foods) {
    	printf "Food: %s Animals who ate it: %d\n",
    	       raiseCase(f), length(foods[f])
    	printf "========\n"
    	for (a in foods[f]) {
    	    printf "%s\n", a
    	}
    	printf "\n"
        }
    }
    
    function raiseCase(s) {
        return toupper(substr(s, 1, 1)) substr(s, 2)
    }
    
    $ awk -f animal_food.awk < animal_food.in.txt
    Food: Apples Animals who ate it: 1
    ========
    Dog
    
    Food: Carrots Animals who ate it: 2
    ========
    Bear
    Dog
    
    Food: Chicken Animals who ate it: 1
    ========
    Bear
    
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: