Sort by custom alphabet

9

The challenge is to make a program that sorts a list of words, only that the words need to be in the order of a random given alphabet.

Your program will accept a string of comma-separated words and a new alphabet.
Your program will output every word in the same way in the new sorted order.

Example:

Input:

home,oval,cat,egg,network,green bcdfghijklmnpqrstvwxzaeiouy

Output:

cat,green,home,network,egg,oval

This is a , so the winner is the person with the shortest program.

This is my first challenge so any improvements to the question/challenge are appreciated.

Mathetic

Posted 2014-10-04T20:38:56.987

Reputation: 103

May we take the inputs in a form that is more appropriate to the language? E.g. two separate inputs; a character matrix with one word on each line, and a character vector of letters. A list of strings. Etc. – Adám – 2016-03-10T17:21:55.840

>

  • I take from your example that the alphabet will be separated from the words by a space. Is that correct? 2. Will the words always be in lowercase?
  • < – Dennis – 2014-10-04T20:51:54.463

    @Dennis yes to both – Mathetic – 2014-10-04T20:53:35.467

    1That is a mistake. I will edit that. – Mathetic – 2014-10-04T21:24:44.013

    +1 OK question (for a first try ;-)). But I'm not seeing the relevance of the title - perhaps you can rename it to Sort by custom alphabet or something more creative? – Digital Trauma – 2014-10-04T21:45:31.987

    @DigitalTrauma Yeah that might be better. I tried to play a little with the words. I aimed for a reference to ascii and utf-8 and the like to ask which it is. But that one failed. I'll change it to your suggestion which was better. – Mathetic – 2014-10-04T22:05:08.073

    Answers

    2

    CJam, 26 19 17 bytes

    rr:A;',/{Af#}$',*
    

    Try it online.

    Test case

    $ cjam sort.cjam <<< 'home,oval,cat,egg,network,green bcdfghjklmnpqrstvwxzaeiouy'
    cat,green,home,network,egg,oval
    

    How it works

    rr                    " Read two whitespace-separated tokens from STDIN. ";
      :A;                 " Save the second token (the alphabet) in A.       ";
         ',/              " Split the remaining token at commas.             ";
            {Af#}$        " Sort by the chunks' characters' indexes in A.    ";
                   ',*    " Join, separating by commas.                      ";
    

    Dennis

    Posted 2014-10-04T20:38:56.987

    Reputation: 196 637

    Well, since u also made used the same approach, mine doesn't really make any sense now. – Optimizer – 2014-10-04T21:11:34.257

    @Optimizer: You beat me by eight seconds. If you undelete your answer, I'll roll mine back. – Dennis – 2014-10-04T21:16:22.937

    No, I think its a trivial and very obv change. I should have looked at your updates before posting my answer in the first place :) – Optimizer – 2014-10-04T21:17:25.477

    4

    Bash+coreutils, 37 bytes

    tr ,$2 \\na-z<<<$1|sort|tr \\na-z ,$2
    

    Output:

    $ ./alphasort.sh home,oval,cat,egg,network,green bcdfghijklmnpqrstvwxyzaeiouy
    cat,green,home,network,egg,oval, $ 
    

    Digital Trauma

    Posted 2014-10-04T20:38:56.987

    Reputation: 64 644

    1Nice way of dealing with the commas! – Dennis – 2014-10-04T21:41:38.187

    2

    Pyth, 19 characters

    j\,o_mx_zdNchczd\,
    

    Test:

    $ pyth -c "j\,o_mx_zdNchczd\," <<< 'home,oval,cat,egg,network,green bcdfghjklmnpqrstvwxzaeiouy'
    cat,green,home,network,egg,oval
    

    Explanation:

                                Implicit: d=" "
                                Implicit: z=input()
    j\,                         ",".join(
       o                                 order_by(lambda N:
        _                                                  rev(
         m                                                     map(lambda d:
          x_zd                                                              rev(z).index(d),
          N                                                                 N),
        chczd\,                                            z.split(" "[0].split(",")
    

    Essentially, it sorts the chunks, with a key of the list of indexes of the characters in the string, then joins them on commas. The reversal businesses is shorter than spliting the string again.

    isaacg

    Posted 2014-10-04T20:38:56.987

    Reputation: 39 268

    18 bytes: j\,_omx_zdNchczd\, – Dennis – 2014-10-05T15:43:16.457

    @Dennis very clever, thank you. – isaacg – 2014-10-05T20:48:53.883

    1

    Ruby, 53 50 bytes

    a,b=$*
    $><<a.split(?,).sort_by{|w|w.tr b,'a-z'}*?,
    

    I'm using Ruby's tr to replace the custom alphabet with a-z before sorting. Input is via command-line argument.

    Martin Ender

    Posted 2014-10-04T20:38:56.987

    Reputation: 184 808

    You can shave off a byte if you use $><< to print to screen (you can remove the space then). You can shave off another two bytes by assigning $* to variables like so: a,b=$* and using #sort_by instead of #sort_by!. – britishtea – 2014-10-05T20:10:00.437

    @britishtea Thanks. I thought I would need *$* (which I had at first and which is the same length). – Martin Ender – 2014-10-05T20:32:06.083

    0

    Clojure, 115 bytes

    #(apply str(butlast(interleave(sort-by(fn[w](apply str(map(zipmap(sort %2)%2)w)))(re-seq #"[a-z]+"%))(repeat \,))))
    

    Wow, this started of well with (sort-by(fn[w](mapv(zipmap(sort %2)%2)w))) but then I realized vec don't get sorted the same way as strings, and interleaving those commas takes significant amount of code as well.

    NikoNyrh

    Posted 2014-10-04T20:38:56.987

    Reputation: 2 361

    0

    JavaScript (E6) 102 119

    Sort with a mapping function 'M' based on the alphabet in variable 'a'
    With IO using popup (prompt + alert)

    x=prompt().split(/[ ,]/),
    a=x.pop(),
    M=w=>[10+a.search(c)for(c of w)]+'',
    alert(x.sort((a,b)=>M(a)>M(b)))
    

    As a (testable) function with 1 string parameter, returning a string array (92)

    F=x=>(
      M=w=>[10+a.search(c)for(c of w)],
      x=x.split(/[ ,]/),
      a=x.pop(),
      x.sort((a,b)=>M(a)>M(b))
    )
    

    Test In FireFox/FireBug console

    F('home,oval,cat,egg,network,green zyxwvtsrqpnmlkjhgfdcbaeiou')
    

    Output

    ["network", "home", "green", "cat", "egg", "oval"]
    

    edc65

    Posted 2014-10-04T20:38:56.987

    Reputation: 31 086

    1-4 if you replace your sort function with (M(a)>M(b))-(M(a)<M(b)) – DocMax – 2014-10-05T05:48:34.320

    @DocMax very nice. It turns out that it's even simpler than that (http://stackoverflow.com/a/7232172/3640407)

    – edc65 – 2014-10-05T08:26:06.337

    If you reuse prompt for input and output and alias it you can avoid the split call by taking the inputs separately. I think that should save a few characters. – Ingo Bürk – 2014-10-05T13:45:05.897

    Also I'm only on my phone right now but why is M so complex? Wouldn't it work to use M=w=>[...a].indexOf(w)? I can't test it right now, unfortunately. – Ingo Bürk – 2014-10-05T13:47:23.983

    @IngoBürk w is a word, not a character. M replace each character in w with its position in a. – edc65 – 2014-10-05T14:04:49.667

    Ah, of course. Suddenly the 10 in there makes sense to me, too :) I don't know why I thought about characters.. – Ingo Bürk – 2014-10-05T14:33:47.927

    0

    Python, 131

    w,a=input().split()
    print(",".join(sorted(w.split(","),key=lambda s:"".join(["abcdefghijklmnopqrstuvwxyz"[a.find(c)]for c in s]))))
    

    There should be plenty of room for improvement.

    monopole

    Posted 2014-10-04T20:38:56.987

    Reputation: 1 559

    You don't have to use a key as the sort function - just use the list of a.find(c) directly. – isaacg – 2014-10-05T10:07:34.857