

G()('al') - eatnumber1
https://github.com/eatnumber1/goal

======
csandreasen
I'm pretty sure this is cheating, but...

    
    
      #!/bin/sh
      grep -e "g\(()\)*('al')" $0 | sed 's/()/o/g' | sed "s/('al')/al/"
      exit
      g()('al')
    

On its own, g()('al') is valid but g()()('al') is a syntax error. Also, bash
and sh don't have non-numeric return values, so regardless of the solution
you're stuck with printing.

~~~
eatnumber1
This is a great incomplete solution. Can you submit a pull-request for it?

~~~
csandreasen
Just to clarify, I think it's a non-solution because the g()('al') is never
actually executed - grep does all the work. You can add as many parenthesis as
you want. The "exit" is there because you'll get a syntax error if you try to
execute g()()('al'). g()('al') by itself does nothing (I'm not even sure why
it's not flagged as a syntax error).

~~~
eatnumber1
The three people who are judging this had a long discussion over this case,
and basically decided that since it is in the file, it's fine. We frown on it
a little because it's basically self-modifying code, but it's better than
nothing for bash.

~~~
tolmasky
I actually prefer it vs. frowning on it for the record ;)

------
pathikrit
Quite trivial in idiomatic Scala:

    
    
      case class Goal(count: Int) {
        def apply() = Goal(count + 1)
        def apply(s: String) = s"g${"o" * count}$s"
      }
    
      object Goal {
        def g() = Goal(1)
      }
    
    

Non-idiomatic shorter answer:

    
    
      case class g(p: String = "go") {
        def apply() = g(p + "o")
        def apply(s: String = "o") = p + s
      }

~~~
tolmasky
This looks great! Can you submit a pull request? These things are coming in
really fast and its way easier to take that way.

------
juol
C#

    
    
        using System;
        using System.Text;
    
        namespace Goal
        {
            class Program
            {
                static void Main(string[] args)
                {
                    Console.WriteLine(G("al"));
                    Console.WriteLine(G()("al"));
                    Console.WriteLine(G()()()()()("al"));
                }
    
                static StringBuilder accumulator = new StringBuilder();
                delegate dynamic GoalDelegate(string s = "o");
    
                static dynamic G(string s = "o")
                {
                    switch (s)
                    {
                        case "o":
                            accumulator.Append("o");
                            return (GoalDelegate)G;
                        case "al":
                            string result = "G" + accumulator.ToString() + "al";
                            accumulator.Clear();
                            return result;
                        default:
                            return null;
                    }
                }
            }
    
        }

~~~
recursive
Here's my C# solution that uses no global state, and features a cool (I think)
variadic lambda.

    
    
        using System;
        using System.Linq;
    
        class Program {
            static void Main() {
                Console.WriteLine(g("al"));
                Console.WriteLine(g()("al"));
                Console.WriteLine(g()()("al"));
                Console.WriteLine(g()()()("al"));
                Console.WriteLine("Press any key to continue.");
                Console.ReadKey();
            }
    
            delegate dynamic Goal(params string[] args);
    
            static dynamic g(string suffix = null, string prefix = "g") {
                if (suffix == "al") return prefix + suffix;
                return (Goal)(a => g(a.FirstOrDefault(), prefix + "o"));
            }
        }
    

It was a fun exercise. I found that creating a github pull request was not
such a fun exercise, and took about 10x longer than the actual task at hand.
Perhaps I could learn to do it more smoothly with practice.

------
zeeboo
I made this Go one that might be cheating because instead of the ("al") call
returning a string, you get a value that implements the String method. Works
with fmt.Println :)

[http://play.golang.org/p/zrp2sO6ZLU](http://play.golang.org/p/zrp2sO6ZLU)

~~~
personZ
This is close to identical to what I did, but the use of a global just felt
too dirty. Still trying to figure out the use of a closure on it.

~~~
eatnumber1
Definitely submit a pull-request if you figure out how to do it :)

------
bobbyi_settv
The "complete" solutions for Python in the repo don't actually work because
they don't reset the state. If you add a final line of:

    
    
      print g('al')
    

for solution1 or:

    
    
      print m('rton')
    

for solution2, you'll find they don't print gal/ mrton.

Here's what I came up with before looking at those solutions that seems to
work:

    
    
      def g(arg=None):
          if arg == 'al':
              return 'gal'
          def inner(arg=None):
              if arg == 'al':
                  return 'g' + (inner.counter * 'o') + 'al'
              inner.counter += 1
              return inner
          inner.counter = 1
          return inner

~~~
eatnumber1
Resetting the state isn't one of the rules ;)

I'd make a solution which resets the state linked by the table though, so
please submit one!

~~~
bobbyi_settv
Rule 7 says:

    
    
       g('al') must return "gal".
    

If you add

    
    
       assert g('al') == 'gal'
    

as the last line of solution 1, the assertion will not pass. I'm not saying
there is a rule that mentions "resetting state". I'm saying that their failure
to reset state is the bug leading to them not following the rules.

~~~
nickdepinet
Thanks for pointing this out, it's now fixed.

[https://github.com/eatnumber1/goal/pull/18](https://github.com/eatnumber1/goal/pull/18)

~~~
bobbyi_settv
Nick,

That helps but doesn't completely solve the state problem. Try adding these
two lines to the end of the program:

    
    
        g()()()()()
        print g('al')
    
    

I think 'gal' should be printed here. Rule 7 says that's what your function
should return given 'al', and the fact that we've called it in some other way
before doesn't change the fact that it is required to return 'gal' given 'al'.

The solution I posted above handles this scenario (and, as a bonus, is thus
threadsafe in case multiple people were doing g()()()('al') simultaneously).

------
morganhankins

      # goal.rb
      module G
        def [](o=nil)
          o ? "g#{values[0].to_s}al" : ({ :n => values[0].to_s + "o" }.extend G)
        end
      end
    
      g = {}.extend G
      
      eval DATA.read.gsub("(", "[").gsub(")", "]")
      

__END__

    
    
      gal = g('al')
      p gal
      
      goal = g()('al')
      p goal
    
      goooooooal = g()()()()()()()('al')
      p goooooooal
      
      # ruby goal.rb
      # "gal"
      # "goal"
      # "goooooooal"
    
    

#
[https://gist.github.com/morganhankins/de13ee378907143a7789](https://gist.github.com/morganhankins/de13ee378907143a7789)

------
GuiA
The table at the bottom is interesting. I'd love to read articles about why
it's impossible in language X. E.g. I'm familiar with C/Python and can
implement a solution, and am surprised that it'd be impossible in Ruby - I
don't know Ruby, and would love to know why.

More generally, what properties must a programming language satisfy for this
problem to be solvable in it?

My current intuition is that if a language does not denote function calls with
() enclosing arguments, AND if a language does not support metaprogramming
(eg. LISP macros), then the problem is not solvable in it. Still thinking
about it.

~~~
eatnumber1
For the impossible bullets, they link to informal arguments as to why it's
impossible. The ruby one has code - it's a syntax error.

~~~
GuiA
The bullets link to non-solutions, which are not enough to formally prove that
it is impossible to solve this challenge in the language.

~~~
eatnumber1
Agreed. These are informal. If you want to make a formal proof that it's
impossible, I'll make a new category.

------
nathangrigg
Python:

    
    
        def g(a='', n=0):
            return 'g '+ 'o'*n + a if a else lambda a='': g(a, n+1)

------
kylec
Ugh, so many solutions that mutate internal state. I went for a more purely
functional approach and kept track of the count with a function parameter
(JavaScript):

[https://github.com/kylecronin/goal/commit/70c9277ec99f80dca2...](https://github.com/kylecronin/goal/commit/70c9277ec99f80dca2b7b01d40766119a1f44e76)

------
Veritaas
The ruby non-solution seen here:

[https://github.com/eatnumber1/goal/blob/master/non-
solutions...](https://github.com/eatnumber1/goal/blob/master/non-
solutions/ruby/nonsoln1/goal.rb)

is actually doable if you parse the error.

~~~
capicue
But it requires eval-ing a string literal instead of actually having g()("al")
as an expression itself

------
jsmeaton
Here's my attempt in python. Started off with the traditional approach but
added a functional one too.

[https://gist.github.com/jarshwah/0998143317f5ccc093b3](https://gist.github.com/jarshwah/0998143317f5ccc093b3)

------
tantalor
This is a syntax error in perl, so impossible?

    
    
      > perl -e "g()()"
      syntax error at -e line 1, near ")("
      Execution of -e aborted due to compilation errors.

~~~
eatnumber1
Can you submit a pull request saying as much in the same format as the Ruby
one?

------
jnbiche
Do languages that don't use () as a function call still have to use the same
syntax? Or is () just a stand-in for a function call?

~~~
eatnumber1
Languages that don't use () still have to use the same syntax. See the haskell
solution.

------
krzysz00
Not too difficult in Common Lisp (the parser is fully exposed to user code, so
I just changed the meaning of "g").

~~~
eatnumber1
Glad to hear it :)

Can you submit a solution then?

~~~
krzysz00
I'm pull request #36.

------
eudox
This could be an interesting use case for Common Lisp reader macros.

~~~
eatnumber1
Agreed! Please submit a solution!

------
whoopdedo
Easy in Lua. You can even write G()'al'

~~~
eatnumber1
Great! Can you submit a pull request?

~~~
whoopdedo
Straightforward solution:

    
    
        function g(o)
          if o then return "gal" end
          o = "o"
          local function go(al)
            if al then
              return "g"..o..al
            else
              o = o .. "o"
              return go
            end
          end
          return go
        end
        print(g()('al'))
    

More amusing and hackish solution:

    
    
        setmetatable(_G, -- or _ENV, but maintain 5.1 compatibility
          { __index = function(_, g)
            local o = ""
            local function go(al)
              if al then
                return g..o..al
              end
              o = o.."o"
              return go
            end
            return go
          end})
        print(g()('al'))
        print(G()'al')
        print(Wh()()'pdedo')

