| 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) "