1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| in yojis yoji firstCharDict pairs bothCharsDict results out timeToRun |

in := FileStream fileNamed: 'in.txt'.
yojis := OrderedCollection new.
[(yoji := in nextLine) notNil] whileTrue: [yojis add: yoji].
in close.

timeToRun := [
    firstCharDict := yojis
        groupBy: [:each | each first]
        having: [:group | group size > 1].

    pairs := OrderedCollection new.
    yojis do: [:first |
        firstCharDict at: first last ifPresent: [:found |
            found do: [:second | pairs add: {first. second}]]].

    bothCharsDict := pairs
        groupBy: [:pair | {pair first first. pair second last}]
        having: [:group | group size > 1].

    results := OrderedCollection new.
    bothCharsDict do: [:val | val combinations: 2 atATimeDo: [:pair |
        | quartet |
        quartet := pair first, pair second.
        (quartet asSet size = 4 and: [quartet first last ~= quartet last first])
            ifTrue: [results add: quartet]]]
] timeToRun.

out := FileStream fileNamed: 'out.txt'.
results do: [:quartet |
    out nextPutAll: quartet first; cr.
    (2 to: 3) do: [:idx |
        out nextPut: (quartet third at: idx).
        out nextPutAll: '  '.
        out nextPut: (quartet second at: idx); cr].
    out nextPutAll: quartet last; cr; cr].
out edit.

^{results size. timeToRun}   "=> #(11712 13835) "