Friday, February 19, 2016

Tiny job application problem solved in Clojure

Today Álvaro García passed me this problem to play with.

I solved it first in the REPL:

user=> (def text "epqiiqwdiwgyka_vsqtsujeqqicnhyivo_sigwasmkwgsih_akl_gtnkhgikgveidpmt
#_=> qybpxpnnpbxkwpisgjmdzgh_ojysbtsnsvxvuhguocp_qc_vouxqmg_cetlpmounxnvg
#_=> ldcpem_jodnmklgonocekdkjwkdoilajk_nxujykigsolengqmnqofpseqaamvpsooga
#_=> spyhoojennefwvljpvsqtgnceg_hsowqvycjkuxdtfbxfloewkphmvkftjlsasvwid_u
#_=> qcsgn_ypiqjytygiwyziqdjpxgpuunymadnclpdlmmulitsnqlwciotbmyfuummjynne
#_=> slnit_lpykdafkpydzkntbud_gigjgmu_uqjjmdzpwteodjpuzndxaqmsjdjjamnwoes
#_=> ajcffkaaoilpyydlkyxauagfcjbabapax_ndlgtpwnud_jpnkiokviqjhyopmjtgtbyo
#_=> iyfbjdhknimlah_cxfzwspqoscffiyvabtjjuc_liaqbcuomuytdqfy_xaixiiqqdpds
#_=> uuimzh_ywwcmodxhfxjplyixotjkeawauxltekptuieekpbokbanumffatbtiacnywhw
#_=> iqxebnosninpzfjmatvnyuspyeu_ziapvogconld_cxfcytkcp_bvsppz_dw_ndlpkhf
#_=> zdlxbo_vaflmailjvccgsuclyhojganjqxzmqflpze_hqhlul_ybaagtiuokbzaxhmec
#_=> olsptiexvvmhbdoelgmcffulcebhlyzd_m_qxkbfvnxykdudpxefsm_aqpqtnhxvswht
#_=> owqnbm_mgejjpyumm_mqbkiuulanbmzllmuqlfftmcxtybmijfuwaknefhekwgujpjqg
#_=> leu_sjtbszotcygiclkwcbmnvgsoqaqqkkgeaslhvfbtlgpnxgpzxp_vyjinlwwfbvtn
#_=> twogmnpxghabpxxgzlyirrrrrbbcrrrnbjpcrrrqykhrrrscarrrdnlxrrrrtudrrrr_
#_=> ntrbyrqlddbycypcccqongpgexhnabavrmebeofrxsnrilprveetxaranjyfmrisrewp
#_=> r_y_lgsrsedbn_rfrieusemhpfa_plkifjipvwaqvnenrrrzybsrbeurbhfrvrrzghr_
#_=> zpgiyrrrqsnnrrrbhvdrrrqkpdrraqvkeueszfpkj_fm_claw_oetbgurbdocb_rsnzr
#_=> cyvrvnrvaurbscimurtbriikrfdjlizribdjwkror_gnlzmshwccqcx_huaafbvituxo
#_=> ru_hohxwrrrhnbttrrriyyirrrnibricrxftrrrrvqvrrrrhjorehroldibsmquelwvy
#_=> jebkolbbnauompgqdhlbnsfbbdiudoeibwstdg_acsazhtgfufidogmyvtya_dfwihto
#_=> elucbtlcbaijlcuhfvhesgluiwttsdnqqshnoqumccyqtko_zh_fii_wlsspysdqdpad
#_=> fvfewlsojavmuaixyxpw_xcwxuatceosdqgmsbbagjmmblouvnywmqqakmmtuasfovol
#_=> _ogksdukwp_fkxuh_vfhuhfyfvvfqhqxecxsoctcqgpianhtnkbqlltwyhxotfksoewm
#_=> elxobjgwlyfaeoxsfohhguidoftbsainwovvglynsgjixon_nvuwflsfbca_xnnesvco
#_=> mceh_gigjxpllckcooagidcpbqxtnejlnlsccocuvcvge_fvjjbyqdkjceia_mkcvbzl
#_=> zwlxbdjihvpmdcvmssuvktwiqbeivtieol_bu_huumzmlxx_kd_vksmohgzl_fxwfdue
#_=> lqgfkgzxciwmuduozfbaxstxkwegescggkpxfpeenhb_whqhethcateqdvnxhpt__bja
#_=> _uiyxchmfkblmdwtyp_ktontmufw_isdflelsbgjizxvqbciuadfxxjaqbluofkgkkkh
#_=> jbvohisfla_cspbmuezqohnyijyimwgdeszutgnaoagbhku_wwdtylbbiyvbpoumgyid
#_=> w_xwg_fkogabccip_wouclnjcgdpwwxxvvvwkmmbgfeactbcksxqovqthtjfjghijwwh
#_=> ydfieyssbjtfqgqyjnmwfpesljmwapvbptucadontbobnspch_i_dxheklulncdsdnic
#_=> bnjjjedkaokw_ahcolvbcnmqtoakonpgzjufqlnn_uve_uumaufjasfvfcv_cbcuk_hd
#_=> zigkahchzfqjphjwcbjwmozyodhu_tsqtafwidgmc_snhhkleyvmzdtawdodzfmekuee
#_=> mnshz_xz")
#'user/text
user=> (def message "abcdefghijklmnopqrstuvwxyz_")
#'user/message
user=> (def frequecies-by-ch (frequencies text))
#'user/frequecies-by-ch
user=> (sort-by #(frequecies-by-ch %) message)
(\z \y \x \w \v \q \k \j \h \t \p \e \d \g \m \f \_ \s \r \a \l \u \c \o \n \i \b)
user=> (reverse (sort-by #(frequecies-by-ch %) message))
(\b \i \n \o \c \u \l \a \r \s \_ \f \m \g \d \e \p \t \h \j \k \q \v \w \x \y \z)
user=> (take-while
#_=> #(not= % \_)
#_=> (reverse (sort-by #(frequecies-by-ch %) message)))
(\b \i \n \o \c \u \l \a \r \s)
user=> (apply
#_=> str
#_=> (take-while
#_=> #(not= % \_)
#_=> (reverse (sort-by #(frequecies-by-ch %) message))))
"binoculars"
Then I collected all the code in the extract-info function:

user=> (defn extract-info [message text]
#_=> (let [frequecies-by-ch (frequencies text)]
#_=> (->> message
#_=> (sort-by #(frequecies-by-ch %))
#_=> reverse
#_=> (take-while #(not= % \_))
#_=> (apply str))))
#'user/extract-info
user=> (extract-info message text)
"binoculars"

4 comments:

  1. That's a neat little test. I had a go before comparing yours with mine:

    (as-> text $
    (frequencies $)
    (sort-by val $)
    (reverse $)
    (map first $)
    (apply str $)
    (clojure.string/replace $ #"_.+" ""))

    Six of one, half dozen the other I guess. ;-)

    ReplyDelete
  2. My variation:

    (def input "epqiiqwdiwgyka_vsqtsu.....
    (->> input
    frequencies
    (sort-by val)
    (map key)
    reverse
    (apply str)
    (re-find #"[^_]+"))

    And with Bash:

    grep -o . input|sort|uniq -c|sort -nr|awk '{printf $2}'|grep -oP "[^_]+"|head -1

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. The reverse operation can be done away with:

    (def input "epqiiqwdiwgyka_vsqtsu.....
    (->> input
    frequencies
    (sort-by #(-' (val %)))
    (map key)
    (apply str)
    (re-find #"[^_]+"))

    ReplyDelete