# RabbitFarm

### 2022-04-17

#### The Weekly Challenge 160 (Prolog Solutions)

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

## Part 1

You are given a positive number, \$n < 10. Write a script to generate english text sequence starting with the English cardinal representation of the given number, the word "is" and then the English cardinal representation of the count of characters that made up the first word, followed by a comma. Continue until you reach four.

### Solution

``````
cardinal(1, one).
cardinal(2, two).
cardinal(3, three).
cardinal(4, four).
cardinal(5, five).
cardinal(6, six).
cardinal(7, seven).
cardinal(8, eight).
cardinal(9, nine).
cardinal(10, ten).

four_is_magic(N) --> {between(1, 9, N), \+N == 4,
cardinal(N, Cardinal),
atom_codes(Cardinal, Codes),
length(Codes, Count)},
[N-Count], four_is_magic(Count).
four_is_magic(N) -->  {between(1, 9, N), N == 4}, [N-magic].

print_magic([]):-
nl.
print_magic([H|T]):-
N-Count = H,
\+ N == 4,
cardinal(N, Cardinal),
cardinal(Count, CountCardinal),
format("~a is ~a, ", [Cardinal, CountCardinal]),
print_magic(T).
print_magic([H|T]):-
N-_ = H,
N == 4,
cardinal(N, Cardinal),
format("~a is ~a", [Cardinal, magic]),
print_magic(T).

main(N) :-
phrase(four_is_magic(N), FourIsMagic),
print_magic(FourIsMagic).
``````

### Sample Run

``````
\$ gprolog --consult-file prolog/ch-1.p
| ?- main(6).
six is three, three is five, five is four, four is magic

true ?

(1 ms) yes
| ?- main(_).
one is three, three is five, five is four, four is magic

true ? ;
two is three, three is five, five is four, four is magic

true ? ;
three is five, five is four, four is magic

true ? ;
five is four, four is magic

true ? ;
six is three, three is five, five is four, four is magic

true ? ;
seven is five, five is four, four is magic

true ? ;
eight is five, five is four, four is magic

true ?

(1 ms) yes

``````

### Notes

Prolog has an interesting history of generating text. This is one of the more simple applications I will admit. Here I use a DCG to generate the sequence and then a recursive set of predicates to print the associated text.

In typical Prolog fashion, as shown in the sample output, we can not only generate a sequence with a specified starting point, but all such sequences.

## Part 2

You are give an array of integers, @n. Write a script to find out the Equilibrium Index of the given array, if found.

### Solution

``````
equilibrium_index(Numbers, I):-
member(N, Numbers),
append(Left, [N|Right], Numbers),
sum_list(Left, SumLeft),
sum_list(Right, SumRight),
SumLeft == SumRight,
nth(I, Numbers, N).

main:-
(equilibrium_index([1, 3, 5, 7, 9], I), format("~d~n", [I]); format("-1~n", _)),
(equilibrium_index([1, 2, 3, 4, 5], J), format("~d~n", [J]); format("-1~n", _)),
(equilibrium_index([2, 4, 2], K), format("~d~n", [K]); format("-1~n", _)), halt.
``````

### Sample Run

``````
\$ gprolog --consult-file prolog/ch-2.p
| ?- main.
4
-1
2
``````

### Notes

This problem was very "Prolog shaped" in my opinion! Just from reading the problem statement I could picture the standard Prolog predicates that could be used here. Prolog is not a language which naturally lends itself to code golf contests but in terms of simple elegance this is quite a compact solution!

## References

Challenge 160

posted at: 09:59 by: Adam Russell | path: /prolog | permanent link to this entry

#### Four is Equilibrium

The examples used here are from The Weekly Challenge problem statement and demonstrate the working solution.

## Part 1

You are given a positive number, \$n < 10. Write a script to generate english text sequence starting with the English cardinal representation of the given number, the word "is" and then the English cardinal representation of the count of characters that made up the first word, followed by a comma. Continue until you reach four.

### Solution

``````
use strict;
use warnings;

my %cardinals = (
1 => "one",
2 => "two",
3 => "three",
4 => "four",
5 => "five",
6 => "six",
7 => "seven",
8 => "eight",
9 => "nine"
);

sub four_is_magic{
my(\$n, \$s) = @_;
\$s = "" if !\$s;
return \$s .= "four is magic" if \$n == 4;
\$s .= \$cardinals{\$n} . " is " . \$cardinals{length(\$cardinals{\$n})} . ", ";
four_is_magic(length(\$cardinals{\$n}), \$s);
}

MAIN:{
print four_is_magic(5) . "\n";
print four_is_magic(7) . "\n";
print four_is_magic(6) . "\n";
}
``````

### Sample Run

``````
\$ perl perl/ch-1.pl
five is four, four is magic
seven is five, five is four, four is magic
six is three, three is five, five is four, four is magic
``````

### Notes

I was thinking of a clever way I might do this problem. I got nothing! Too much Easter candy perhaps? Anyway, I am not sure there is much tow rite about here as it's an otherwise straightforward use of hashes.

## Part 2

You are give an array of integers, @n. Write a script to find out the Equilibrium Index of the given array, if found.

### Solution

``````
use strict;
use warnings;

sub equilibrium_index{
for my \$i (0 .. @_ - 1){
return \$i if unpack("%32I*", pack("I*",  @_[0 .. \$i])) == unpack("%32I*", pack("I*",  @_[\$i .. @_ - 1]));
}
return -1;
}

MAIN:{
print equilibrium_index(1, 3, 5, 7, 9) . "\n";
print equilibrium_index(1, 2, 3, 4, 5) . "\n";
print equilibrium_index(2, 4, 2) . "\n";
}
``````

### Sample Run

``````
\$ perl perl/ch-2.pl
3
-1
1
``````

### Notes

Like Part 1 above this problem allows for a pretty cut and dry solution. Also, similarly, I can't see a more efficient and/or creative way to solve this one. Maybe I should have just gone for obfuscated then?!?!? In any event, if nothing else, I always like using pack/unpack. I always considered it one of Perl's super powers!

## References

Challenge 160

posted at: 09:59 by: Adam Russell | path: /perl | permanent link to this entry