Receipt Bank Logo

Haiku generator

Haiku generator

A legend says that a Dutch engineer read a Japaneese hauki and got very impressed with it. He was so mesmerized that he wanted to surprise the love of his heart, a Bulgarian immigrant, with a haiku every day. Since he’s an engineer he decided to write a program to help him with that.

But, the year being 1991, no decent programming language existed and, like many engineers, he over-engineered the task and started writing his own programming language for the task at hand. 25 years later, the language is still not finished and he still has no time for the haiku.

Help him by using the now present, awesome Ruby language to write the shortest possible code to produce a haiku from a given dictionary.

Input

A dictionary of words. Her vocabulary is still quite limited.

Syllables in words are separated by dashes.

Output

A string with 3 lines, first one having exactly 5 syllables, second one having exactly 7 syllables, third line having exactly 5 syllables. 17 syllables total. It has to be different every time, otherwise reading them will get boring. It has to only use words from the dictionary or she will not understand it.

Example:

DICTIONARY = %w(
  clean code test writes creates de-ve-lops sim-ple de-sign fast es-sen-tial de-cou-pled
  main-tain-able read-able makes runs smooth thinks or-tho-go-nal beau-ti-ful di-vine
  cor-rect i-dio-matic ro-bust soft-ware con-cise craft-man-ship know-ledge-able best
  ex-pli-cit re-fac-tor right de-ci-sions pos-si-ble bet-ter shines through
)

haiku(dictionary) =>
"de-cou-pled di-vine\nde-ve-lops through right test thinks\nbeau-ti-ful code writes"

Leader board

The lower the score - the better. It is the shortest solution that wins.

If you're among the first 5 stop by out booth to claim your reward.
Winner!
Nickname: janosch-jo
   Score: 74 
def haiku d
  [4,6,4].map { |c|
    l = d.sample(rand 5) * ' ' until l&.count(' -') == c
    l
  } * ?\n
end
Winner!
Nickname: rambo
   Score: 102 
def haiku(d)
    [5, 7, 5].map { |n|
    w = []
    w = d.sample(rand 5) while w.reduce(0) { |a, w| a + w.count('-') + 1 } != n
    w * ' '
  } * "\n"
end
Winner!
Nickname: J-_-L
   Score: 103 
def haiku w
$_=((w+[$/]*9).shuffle*' ').gsub(/ 
 /,$/)until/^#{a='(\w+[- ]){4}\w+\n'}(\w+[- ]){6}\w+\n#{a}/ 
$&
end
Winner!
Nickname: R
   Score: 103 
def haiku(d)
  [5, 7, 5].map { |s|
    t = []
    o = 0
    while o != s
      w = d.sample
      q = w.count('-')+1
      next if q + o > s
      t << w
      o += q
    end
    t * ' '
  } * "\n"
end
Winner!
Nickname: Rosa
   Score: 106 
def haiku(d)
  [[23,14],[35,24],0..4].map { |v| d.shuffle.sort_by { |w| w.split("-").size }.values_at(*v)*" " }*"\n"
end
Nickname: Joskov
   Score: 120 
def haiku i
  [5, 7, 5].map { |a| r = g(i, a); i -= r; r * ' ' } * "\n"
end

def g i, c
  i.shuffle.select { |a| n(a) <= c && c -= n(a) }
end

def n w
  w.count('-') + 1
end
Nickname: david
   Score: 121 
def haiku(z)
  x = -> a {
    y = []
    loop {
      b = z.sample
      d = a - (b.count('-') + 1)
      d >= 0 && (a = d) && (y << b)
      d == 0 && break
    }
    y * ' '
  }
  p [5, 7, 5].map { |e| x[e] } * "\n"
end
Nickname: Dutch engineer
   Score: 123 
def haiku(d)
  [5,7,5].map{|n|(l=->(i){(s=d.shuffle.combination(i).find{|x|i+x.join.count('-')==n})&&s*' '||l[i+1]})[1]}*"\n"
end
Nickname: fp
   Score: 135 
def haiku(d)
  [5,7,5].map do |i|
    d.shuffle.each_with_object("") do |w, c|
      c << d.delete(w)+' ' if (c+' '+w).split(/[\s-]/).count <= i+1
    end.chop
  end*?\n
end
Nickname: Sam-ll
   Score: 135 
def haiku(d)
  [5, 7, 5].map { |x|
  t = 0
  s = []
  until t == x do
    w = d.shuffle.pop
    if (t + c(w)) <= x
      s << w
      t += c(w)
    end
  end
  s. join ' '
  }.join "\n"
end


def c w
  w.split('-').size
end
Nickname: JJ
   Score: 138 
def haiku(d)
  d.shuffle!
  r = /[ -]/
  s = ->(w) { (w * ' ').split(r).size }
  f = ->(n) {
    w = []
    until s[w] == n
      w << d.pop
      w.pop if s[w] > n
    end
    w * ' '
  }
  [5, 7, 5].map { |n| f[n] } * "\n"
end
Nickname: Dalzhe
   Score: 149 
def haiku(d)
  [5,7,5].map { |n|
    i=n
    w=[]
    while i > 0
      e = d.select{|w|w.split("-").size <= i}.sample
      w << d.delete(e)
      i -= w[-1].split("-").size
    end
    w.join(" ")
  }.join("\n")
end
Nickname: cinti
   Score: 149 
def haiku(y)
  [5,7,5].map { |a| 
  b = 0
  d = []
  
  until b == a do
    d << y.delete(y.shuffle.find{ |w| w.split('-').size <= (a - b) })
    b += d.last.split('-').size
  end
  
  d.join ' '
}.join "\n"
end
Nickname: L.E.
   Score: 160 
def haiku(dictionary)
d=dictionary
r=[]
[5,7,5].each{|n|
begin
s=d.sample(rand(1..7))
end while s.map{|x| x.split('-')}.flatten.count!=n
d=d-s
r<<s.join(' ')
}
r.join("\n")
end
Nickname: xsimov
   Score: 198 
def haiku(dictionary)
  [5,7,5].map{|n| add_word(dictionary, n)*' ' }.*"\n"
end
def add_word(d, n, l=[])
  w = d.sample
  l << d.delete(w) if (r = l.reduce(0){|s, i| s + i.count('-')+1} + w.count('-')+1) <= n
  r!=n ? add_word(d, n, l) : l
end
Nickname: leopard
   Score: 202 
def haiku(d)
d.shuffle.map{|e|e.split'-'}.inject([[],[],[]]){|r,s|
[5,7,5].each.with_index{|t,i|
z=r[i].flatten.size
if z<t && t-z-s.size>=0
r[i].push(s)
break
end
}
r
}.map{|e|e.map{|s|s.join '-'}.join ' '}.join"\n"
end
Nickname: alehander42
   Score: 248 
def haiku d
  f = d.group_by { |e| e.count('-') + 1 }
  g=2
  "#{y 5,g,f }\n#{y 7,g,f}\n#{y 5, g,f}"
end

def y x, p, w
  m, s, f = [], 0, []
  while true
    k = w.keys.sample
    q = w[k].sample
    if q
      m << q
      f << k
      s += k
      w[k].delete q
    end
    if s > x
      f.zip(m).each do |g, h|
        w[g] << h
      end
      m, s, f = [], 0, []
    elsif s == x
      return m.join ' '
    end
  end
end
Nickname: kartacha
   Score: 280 
def z(s, k)
  arr = (1..s).flat_map do |c|
    @d.map { |w| w.split('-') }.permutation(c).first(200).select { |a| a.flatten.count == s }
  end[k];  
  
  words = arr.map { |r| r.join('-')  }; 
  words.each { |w| @d.delete(w) };
  words.join(' ')
end

def haiku(d)
  @d = d;
  @l ||= Hash.new(-1);
  k = @l[d.hash] += 1;

  [z(5, k), z(7, k), z(5, k)].join("\n")
end