Skip to content

Instantly share code, notes, and snippets.

@jlogsdon
Forked from isa/gist:2571012
Created May 1, 2012 20:35
Show Gist options
  • Save jlogsdon/2571163 to your computer and use it in GitHub Desktop.
Save jlogsdon/2571163 to your computer and use it in GitHub Desktop.
Convert in less than 30 lines
Question: Convert following into the latter data structure in less than 30 lines:
List:
A, B, C
A, C, E
E, F, D
D, A, J
E, D, J
List
A, B, 1 (frequency)
A, C, 2
A, D, 1
A, E, 1
A, J, 1
B, C, 1
C, E, 1
D, E, 2
D, F, 1
D, J, 2
E, F, 1
E, J, 1
list = [
['A', 'B', 'C'],
['A', 'C', 'E'],
['E', 'F', 'D'],
['D', 'A', 'J'],
['E', 'D', 'J']
] # Or `.split("\n").map { |r| r.split(', ') }` if reading the exact contents
result = Hash.new(0) # All pairs start at a count of 0, prevents the need to ensure a key exists below
list.each do |row|
row.sort!
(row.length - 1).times do
leading = row.shift
row.each { |follow| result[(leading + follow).sort] += 1 }
end
end
@kejadlen
Copy link

kejadlen commented May 1, 2012

Here's mine:

data = [ %w[ A B C ],
         %w[ A C E ],
         %w[ E F D ],
         %w[ D A J ],
         %w[ E D J ] ]

hash = data.inject(Hash.new {|h,k| h[k] = 0 }) do |h,ary|
  ary.combination(2) {|c| h[c.sort] += 1 }
  h
end

hash.sort.each {|k,v| puts "#{k[0]}, #{k[1]}, #{v}" }

@snuxoll
Copy link

snuxoll commented May 1, 2012

A variation of the one posted above:

list = [
  ['A', 'B', 'C'],
  ['A', 'C', 'E'],
  ['E', 'F', 'D'],
  ['D', 'A', 'J'],
  ['E', 'D', 'J']
]

comb = (list.inject([]) { |a,ary| a + ary.combination(2).to_a.map(&:sort) }).sort
hash = Hash.new {|h,k| h[k] = comb.count(k)}
comb.uniq.each {|x| puts "#{x[0]}, #{x[1]}, #{hash[x]}"}

I saved a couple lines by dropping the longer do...end syntax, and taking advantage Hash#new taking a block in a slightly more useful way than the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment