9
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 1. 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? \$\endgroup\$ – Dennis Oct 4 '14 at 20:51
  • \$\begingroup\$ @Dennis yes to both \$\endgroup\$ – Mathetic Oct 4 '14 at 20:53
  • 1
    \$\begingroup\$ That is a mistake. I will edit that. \$\endgroup\$ – Mathetic Oct 4 '14 at 21:24
  • \$\begingroup\$ +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? \$\endgroup\$ – Digital Trauma Oct 4 '14 at 21:45
  • \$\begingroup\$ @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. \$\endgroup\$ – Mathetic Oct 4 '14 at 22:05
2
\$\begingroup\$

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.                      ";
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Well, since u also made used the same approach, mine doesn't really make any sense now. \$\endgroup\$ – Optimizer Oct 4 '14 at 21:11
  • \$\begingroup\$ @Optimizer: You beat me by eight seconds. If you undelete your answer, I'll roll mine back. \$\endgroup\$ – Dennis Oct 4 '14 at 21:16
  • \$\begingroup\$ 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 :) \$\endgroup\$ – Optimizer Oct 4 '14 at 21:17
4
\$\begingroup\$

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, $ 
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice way of dealing with the commas! \$\endgroup\$ – Dennis Oct 4 '14 at 21:41
2
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 18 bytes: j\,_omx_zdNchczd\, \$\endgroup\$ – Dennis Oct 5 '14 at 15:43
  • \$\begingroup\$ @Dennis very clever, thank you. \$\endgroup\$ – isaacg Oct 5 '14 at 20:48
1
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 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!. \$\endgroup\$ – britishtea Oct 5 '14 at 20:10
  • \$\begingroup\$ @britishtea Thanks. I thought I would need *$* (which I had at first and which is the same length). \$\endgroup\$ – Martin Ender Oct 5 '14 at 20:32
0
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You don't have to use a key as the sort function - just use the list of a.find(c) directly. \$\endgroup\$ – isaacg Oct 5 '14 at 10:07
0
\$\begingroup\$

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"]
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ -4 if you replace your sort function with (M(a)>M(b))-(M(a)<M(b)) \$\endgroup\$ – DocMax Oct 5 '14 at 5:48
  • \$\begingroup\$ @DocMax very nice. It turns out that it's even simpler than that (stackoverflow.com/a/7232172/3640407) \$\endgroup\$ – edc65 Oct 5 '14 at 8:26
  • \$\begingroup\$ 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. \$\endgroup\$ – Ingo Bürk Oct 5 '14 at 13:45
  • \$\begingroup\$ 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. \$\endgroup\$ – Ingo Bürk Oct 5 '14 at 13:47
  • \$\begingroup\$ @IngoBürk w is a word, not a character. M replace each character in w with its position in a. \$\endgroup\$ – edc65 Oct 5 '14 at 14:04
0
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.