24
\$\begingroup\$

Given a non-negative integer (n), create a function that returns n in alphabetical order, according to the literal spelling of each digit in n.

Examples:

Input: 101
>> one, zero, one
>> one, one, zero
Output: 110

Input: 31948
>> three, one, nine, four, eight
>> eight, four, nine, one, three
Output: 84913

Input: 5544
>> five, five, four, four
>> five, five, four, four
Output: 5544

Input: 1234567890
Output: 8549176320

Note: the operations in the example are illustrative only and do not need to be included in the output. Only the alphabetically-sorted number needs to be returned.

This is code-golf, so the shortest code in bytes wins.

Edit: the input can be taken in any desired format that best suits your language, and the output can be produced similarly by returning from the function or printing. The input will always be a natural number (including 0) and will not contain leading 0's.

Relevant OEIS entry (A057846) found by @DomHastings

\$\endgroup\$
  • 1
    \$\begingroup\$ Can I also take the number as a string and output a string? \$\endgroup\$ – ThreeFx Jul 7 '16 at 21:04
  • 1
    \$\begingroup\$ @nimi 00 .... \$\endgroup\$ – TuxCrafting Jul 7 '16 at 21:07
  • 5
    \$\begingroup\$ You might want to specify that the input is in decimal, or you'll get some cheeky answers using unary... \$\endgroup\$ – Martin Ender Jul 7 '16 at 21:16
  • 6
    \$\begingroup\$ This is a bit confusing: you wrote in the comments that you expect a numeric type as input and output of the function, but also that it’s okay to print the result instead. So, if the output is 849, does that mean we’re allowed to print the number 849 but not the string "849"? IMO this is just a cumbersome I/O format (bad!) on top of a perfectly fine challenge. \$\endgroup\$ – Lynn Jul 8 '16 at 1:27
  • 1
    \$\begingroup\$ Leading zeroes significant or not? e.g. what does 001 output? If they are significant and the result is not 1, most languages will require strings as input for the simple fact it is crude, impractical and usually nigh on impossible to ask the parser to preserve leading zeroes in base 10 literal numbers. \$\endgroup\$ – cat Jul 8 '16 at 2:56

29 Answers 29

12
\$\begingroup\$

Perl 6,  32  28 bytes

{+[~] .comb.sort: *.Str.uniname}
{+[~] .comb.sort: *.uniname}

Explanation:

{
  # turn the following into a Numeric
  +

  # fold the following list using string concatenation operator
  [~]

    # split $_ into individual characters
    # (implicit method call on implicit parameter)
    .comb

    .sort:
    *.uniname # sort by the Unicode name of the character (digit)
}

Test:

#! /usr/bin/env perl6
use v6.c;
use Test;

my @tests = (
  101 => 110,
  31948 => 84913,
  5544 => 5544,
  1234567890 => 8549176320,
);

# give the lambda a lexical name for clarity
my &int-sort = {+[~] .comb.sort: *.uniname}

plan 3 * @tests;

for @tests -> $_ ( :key($input), :value($expected) ) {
  put '';
  isa-ok $input, Int, "input ($input) is an Int";

  my $output = int-sort $input;

  is $output, $expected, .gist;
  isa-ok $output, Int, "output ($output) is an Int"
}
1..12

ok 1 - input (101) is an Int
ok 2 - 101 => 110
ok 3 - output (110) is an Int

ok 4 - input (31948) is an Int
ok 5 - 31948 => 84913
ok 6 - output (84913) is an Int

ok 7 - input (5544) is an Int
ok 8 - 5544 => 5544
ok 9 - output (5544) is an Int

ok 10 - input (1234567890) is an Int
ok 11 - 1234567890 => 8549176320
ok 12 - output (8549176320) is an Int
\$\endgroup\$
8
\$\begingroup\$

05AB1E, 12 11 10 bytes

•OWÿ¾•vy†J

Explained

•OWÿ¾•        # push sortorder (236719458)
      v       # for each number in sortorder
       y†     # filter to the front
         J    # join
              # implicitly print

Try it online

Saved 1 byte thanks to Adnan

\$\endgroup\$
8
\$\begingroup\$

JavaScript (ES6), 54

Edit same char count, but avoiding the global variable z

Input / output as strings

n=>[...n].sort((a,b)=>n[a]-n[b],n='9487216503').join``

Test

f=n=>[...n].sort((a,b)=>n[a]-n[b],n='9487216503').join``

function test() {
  O.textContent=f(I.value)
}

test()
<input id=I type=number value=31948 oninput='test()'>
<pre id=O></pre>

\$\endgroup\$
  • 2
    \$\begingroup\$ Love this, using the input digits as indices of the string z... \$\endgroup\$ – Dom Hastings Jul 8 '16 at 11:35
6
\$\begingroup\$

Haskell, 62 51 44 bytes

As @nimi suggested, using a list comprehension is shorter than composing functions:

f x=0+read[a|a<-"8549176320",b<-show x,a==b]

For reference my version:

f n=read.(=<<)(\x->filter(==x)$show n)$"8549176320"

The pointfree version is a bit longer:

f=flip(read.)"8549176320".(=<<).flip(filter.(==)).show

Straightforward: Filter the digits in the correct order and then concatenate the result.

\$\endgroup\$
5
\$\begingroup\$

Pyth, 12 10 bytes

ox`C" Ȁ\0

Not sure if it can be golfed further. Input needs to be enclosed in quotes.

2 bytes saved thanks to @isaacg!

In pythonic pseudocode:

                Q = input()
o          Q    sort(Q, key = lambda N:
  `C" Ȁ\0        repr(base256toDec(" Ȁ\0"))
 x        N         .index(N)     # 8 being absent from the number yields -1
                )

Test it here.

\$\endgroup\$
  • \$\begingroup\$ @busukxuan I also get 14 bytes :p. \$\endgroup\$ – Adnan Jul 7 '16 at 23:30
  • \$\begingroup\$ @Adnan revert to numbers then. It seems there isn't a way to compress these numbers... \$\endgroup\$ – busukxuan Jul 7 '16 at 23:33
  • 2
    \$\begingroup\$ Save 2 bytes by replacing 549176320 with C" »Ä\0 \$\endgroup\$ – isaacg Jul 8 '16 at 2:23
  • \$\begingroup\$ @isaacg Thanks! I tried to convert it to base 256 a few times but the result was wrong. How did you do it right? \$\endgroup\$ – busukxuan Jul 8 '16 at 2:45
  • 1
    \$\begingroup\$ You have to escape null bytes by replacing them with \0. That's probably the problem you were running into. \$\endgroup\$ – isaacg Jul 9 '16 at 15:05
4
\$\begingroup\$

Perl, 37 bytes

36 bytes code + 1 byte command line (-F)

say sort{8549176320=~/$b.*$a/||-1}@F

Usage example:

echo -n "04823" | perl -F -M5.010 entry.pl
\$\endgroup\$
3
\$\begingroup\$

MATL, 19 bytes

Vt'8549176320'&m2$S

Try it online!

Explanation

V              % Implicitly input number. Convert to string (¹)
t              % Push copy of (¹)
'8549176320'   % Push this string (²), which defines order
&m             % Indices (³) of each element of (¹) in (²)
2$S            % Sort copy of (¹) according to (³). Implicitly display
\$\endgroup\$
3
\$\begingroup\$

Jelly, 11 bytes

“U1°ŀ”OṾf@€

Try it here.

Explanation

“U1°ŀ”O       Get the Unicode ordinals of “U1°ŀ”
                (all of which are coincidentally single bytes
                in the Jelly code page!)
              The result is [85, 49, 176, 320].
       Ṿ      Uneval. This gets us the string “85,49,176,320”.
        f@€   For each char in this string, extract all chars
                from the first command line argument that
                equal it.
\$\endgroup\$
3
\$\begingroup\$

Mathematica 35 78 47 bytes

31 bytes saved thanks to a suggestion by LIAMnYP!

FromDigits@SortBy[IntegerDigits@#,IntegerName]&

IntegerDigits breaks up the number into digits which are then sorted according to their names in English. FromDigits assembles the digits into a base-10 number.


FromDigits@SortBy[IntegerDigits@#,IntegerName]&[1234567890]

8549176320

\$\endgroup\$
  • \$\begingroup\$ By using "SortBy" you don't have the problem of converting the words back to digits. FromDigits@SortBy[IntegerName]@IntegerDigits@#& \$\endgroup\$ – LLlAMnYP Jul 8 '16 at 11:44
  • \$\begingroup\$ Also Interpreter is painfully slow, so that's an added bonus. \$\endgroup\$ – LLlAMnYP Jul 8 '16 at 11:44
  • \$\begingroup\$ Fantastic improvement. \$\endgroup\$ – DavidC Jul 8 '16 at 13:18
  • \$\begingroup\$ 11 bytes in Mtmca, whenever that comes into being. \$\endgroup\$ – Michael Stern Jul 8 '16 at 13:58
3
\$\begingroup\$

C, 142 141 117

Pass parameter as long long * to f(); the function modifies the parameter:

f(long long*n){char*c="8549176320",g[10]={0};for(;*n;*n/=10)++g[*n%10];for(;*c;++c)for(;g[*c-48]--;*n=*n*10+*c-48);}

long long is necessary since the last test case overflowed an int when sorted.

\$\endgroup\$
2
\$\begingroup\$

Python 2 - 95 bytes

def s(n):
    l=list("8549176320")
    return "".join(sorted(list(n),key=lambda x: l.index(x)))

Attempting further golfing...I think the line 2 is unnecessary and this can become 1 lambda.

EDIT: 49 char version in comments, thx to xnor and vaultah for help.

\$\endgroup\$
  • \$\begingroup\$ lambda n:''.join(sorted(`n`,key="8549176320".find)) \$\endgroup\$ – vaultah Jul 7 '16 at 21:11
  • 4
    \$\begingroup\$ @vaultah Nice solution, you should post it! I think you can omit the 8 so that the find gives -1. \$\endgroup\$ – xnor Jul 7 '16 at 21:13
  • 1
    \$\begingroup\$ ooh that's clever @xnor. The shortest I got it to was lambda n: "".join(sorted(n,key="549176320".find)), which is really similar to what you suggested, vaultah. You should post it! \$\endgroup\$ – Jeremy Jul 7 '16 at 21:17
  • 1
    \$\begingroup\$ @Jeremy You should edit that version into your post. \$\endgroup\$ – DJMcMayhem Jul 7 '16 at 22:01
  • 2
    \$\begingroup\$ At least get rid of the superfluous whitespace... Indentation can be done with a single space. Also this is invalid, because the OP stated that output must be a numeric type. \$\endgroup\$ – Mego Jul 7 '16 at 23:29
2
\$\begingroup\$

-- Oracle 11 (SQL): 164 bytes

  SELECT LISTAGG(DECODE(s,0,'zero',TO_CHAR(TO_DATE(s,'j'),'jsp')),',')WITHIN GROUP(ORDER BY 1)FROM(SELECT SUBSTR(&1,level,1)s FROM dual CONNECT BY LEVEL<=LENGTH(&1));

Long form and explanation

  SELECT LISTAGG(DECODE(s,0,'zero',TO_CHAR(TO_DATE(s,'j'),'jsp')),',') WITHIN GROUP (ORDER BY 1)
  FROM ( SELECT SUBSTR(&1,level,1)s FROM dual
           CONNECT BY LEVEL <= LENGTH(&1)
        );

Get the input as parameter to script:

  SELECT &1 FROM dual

"create" rows by using connect by based on length of input:

  CONNECT BY LEVEL <= LENGTH(&1)

Rip out each digit from the string for each position:

  SELECT SUBSTR(&1,level,1)s FROM dual

Convert the digit to Julian date, and back to Char to get spelling:

  TO_CHAR(TO_DATE(s,'j'),'jsp')

Check for zero - special case.

  DECODE(s,0,'zero'

Use LISTAGG function to concatenate rows back into a single row list, comma delimited, ordered alphabetically

  LISTAGG(DECODE(s,0,'zero',TO_CHAR(TO_DATE(s,'j'),'jsp')),',') WITHIN GROUP (ORDER BY 1)

Always fun trying to tweak SQL for things like this ... :) really tests my knowledge of the bugger ...

\$\endgroup\$
1
\$\begingroup\$

Ruby, 60 bytes

->n{n.to_s.chars.sort_by{|c|'8549176320'.index c}.join.to_i}
\$\endgroup\$
1
\$\begingroup\$

Racket, 142 130 bytes

(λ(n)(string->number(list->string(sort(string->list(~a n))char<? #:key(λ(m)(string-ref "9487216503"(-(char->integer m)48)))))))

Of which conversions are more than almost half of the length (76 64 bytes).

\$\endgroup\$
  • \$\begingroup\$ (+ 1 answer) for Racket! \$\endgroup\$ – cat Jul 8 '16 at 2:21
  • \$\begingroup\$ @cat It's useful for me to keep practicing Racket, since it's a way to maintain functional programming knowledge while working on these horribly procedural legacy Java (and slightly-less-legacy Python) programs left to me by my co-workers. I could rant about how having objects does not necessarily make a program object-oriented, but instead of doing that I'll just keep golfing my problems away in Racket. \$\endgroup\$ – Steven H. Jul 8 '16 at 3:05
  • \$\begingroup\$ Hmm... I definitely sympathise, and it's possible and fun to write functional Python, but Java's just Fawful. Maybe you can get your superiors to let you use Scala for the implementation and Java just as glue. :) \$\endgroup\$ – cat Jul 8 '16 at 3:34
  • \$\begingroup\$ By the way, if you like Forth and your eyes get a little tired from reading Lisp inside-out, you should check out Factor, which is Lisp and the CLOS but in a Forth-y postfix and point-free disguise. \$\endgroup\$ – cat Jul 8 '16 at 3:35
1
\$\begingroup\$

TSQL, 260 bytes

Used reversed bubble sort to avoid refering to the length, to save some bytes

Golfed:

DECLARE @ varchar(99)=101

,@i INT=99,@j INT=98WHILE @i>1SELECT
@=IIF(CHARINDEX(x,'598327614')>CHARINDEX(y,'598327614'),STUFF(STUFF(@,@j,1,x),@i,1,y),@),@i-=IIF(@j=1,1,0),@j=IIF(@j=1,@i,@j-1)FROM(SELECT
SUBSTRING(@,@i,1)x,SUBSTRING(@,@j,1)y)z
PRINT @

Ungolfed:

DECLARE @s BIGINT=1234567890

DECLARE @ char(99)=@s,@i INT=99,@j INT=98
WHILE @i>1
  SELECT 
    @=IIF(CHARINDEX(x,'236719458')>CHARINDEX(y,'236719458'),
        STUFF(STUFF(@,@j,1,x),@i,1,y),@), 
    @i-=IIF(@j=1,1,0),
    @j=IIF(@j=1,@i,@j-1)
  FROM(SELECT SUBSTRING(@,@i,1)x,SUBSTRING(@,@j,1)y)z
PRINT CAST(@ as bigint)

Insisting on using integer types as input and output added 37 bytes

\$\endgroup\$
  • \$\begingroup\$ DECLARE @ varchar(99)=101 0.o does 101 get turned to a string automatically? \$\endgroup\$ – cat Jul 8 '16 at 13:30
  • \$\begingroup\$ Also, stuff is an objectively awful function name. squash or shove or pack would be better :P \$\endgroup\$ – cat Jul 8 '16 at 13:31
  • \$\begingroup\$ @cat yes, it gets converted into a string automatically, but that would be cheating according to the descriptino. I agree, stuff is a silly name \$\endgroup\$ – t-clausen.dk Jul 8 '16 at 15:03
  • 1
    \$\begingroup\$ I mean, we might as well just call every function stuff cause that's what functions do: they do stuff. Then your code can look like stuff(stuff(4, 5, stuff), stuff(stuff()).(stuff())()); stuff(stuff) \$\endgroup\$ – cat Jul 8 '16 at 19:24
1
\$\begingroup\$

ClojureScript, 45 bytes

#(apply str(sort-by(vec"9487216503")(str %)))

Uses some screwy string->int conversion from Javascript leak through, so it's not valid Clojure.

\$\endgroup\$
1
\$\begingroup\$

Firebird, 317 bytes

Golfed:

select list(s,'')from(with recursive q as(select 1 p,substring(:a from 1 for 1)s from rdb$database q union all select q.p+1 p,substring(:a from q.p+1 for 1)s from q where q.p<char_length(:a))select s from q order by iif(s=8,0,iif(s=5,1,iif(s=4,2,iif(s=9,3,iif(s=1,4,iif(s=7,5,iif(s=3,7,iif(s=2,8,iif(s=0,9,6))))))))))

Ungolfed:

select list(s, '')
from (
   with recursive q as (
      select 1 as p, substring(:a from 1 for 1) s
      from rdb$database q
      union all
      select q.p + 1 as p, substring(:a from q.p + 1 for 1) as s
      from q
      where q.p < char_length(:a)
   )
   select s
   from q
   order by iif(s = 8, 0,
               iif(s = 5, 1,
                  iif(s = 4, 2,
                     iif(s = 9, 3,
                        iif(s = 1, 4,
                           iif(s = 7, 5,
                              iif(s = 3, 7,
                                 iif(s = 2, 8,
                                    iif(s = 0, 9, 6)))))))))
)

There's no split functionality in Firebird. Instead I created a recursive query to get the next character over and over. Then reselect those while sorting by our proper order. Finally concatenate those results back together in a list. Override the default comma delimiter with blank. I could save 11 bytes by creating a new dummy table instead of rdb$database but I thought that may be against the rules.

\$\endgroup\$
1
\$\begingroup\$

ZX Spectum, machine code, 53 48 47 45 44 bytes

    org 49200 ; #c030

; table converts ascii to alfabetical order
; start from BASIC with any number as : PRINT "1234567890" AND USR 49208

convtab defb 249 ; zero defb 244 ; one defb 248 ; two defb 247 ; three defb 2+205 ; four defb 1+205 ; five defb 246 ; six defb 245 ; seven ; defb 0 ; eight ; defb 3 ; nine ; last 2 conversions hidden in call-command

start Call #2bf1    ; fetch stackindex
    call #2ab2 ; store back
    ld h,#c0    ; set highbyte of table


Sort Push de
loop ld b,d
    ld c,e
    inc de
    ld a,(bc)   ; fetch number
    Ld l,a
    ld a,(de)
    cp 34       ; endmarker "
    Jr z,exit   ; end reached?
    push hl     ; save number
    ld l,a
    Ld a,(hl)   ; convert second number
    pop hl
    cp (hl)     ; compare numbers
    jr nc,loop  ; in order, no swap
swap ld a,(bc)  ; swap original numbers
    ld l,a
    ld a,(de)
    ld (bc),a
    ld a,l
    ld (de),a
Exit pop de
    Ret z
    jr sort     ; check number for order

\$\endgroup\$
  • \$\begingroup\$ With Gnome-sort it can be shortened and table can be 1 byte shorter. New version to come... \$\endgroup\$ – Johan Koelman Jul 19 '16 at 10:25
  • \$\begingroup\$ Gnome-sort here is longer, but other optimizations. \$\endgroup\$ – Johan Koelman Jul 19 '16 at 13:04
0
\$\begingroup\$

Factor, 128

[ 10 base> [ 48 - ] { } map-as dup [ number>text ] map zip [ second first ] sort-with [ first ] map [ 48 + ] ""map-as 10 >base ]

Hooray for builtins! :D

\$\endgroup\$
0
\$\begingroup\$

PHP, 126 bytes

As far as I know php doesn't have any builtins that would really help with this (the best I could do using a usort(str_split()) was 5 bytes longer) so the only thing I'm happy within this answer is the games played with $i to save a couple of bytes on the itteration.

<?php for($i=-1;$i<9;)$a[++$i]=preg_replace("/[^$i]/","",$argv[1]);array_multisort([9,4,8,7,2,1,6,5,0,3],$a);echo implode($a);
\$\endgroup\$
0
\$\begingroup\$

APL, 23 bytes

{⍎n['8549176320'⍋n←⍕⍵]}

Explanation:

  • n←⍕⍵: get the string representation of n and store it in n
  • '8549176320'⍋: find a permutation of n that sorts n given the order 8549176320.
  • n[...]: reorder n by that permutation
  • : evaluate the result (to turn it back into a number)
\$\endgroup\$
  • \$\begingroup\$ Since I/O may be strings, you can remove and . Convert to tradfn by removing { and } and substituting for . Finally, remove 0 as unlisted sorts at the end: n['854917632'⍋n←⍞] \$\endgroup\$ – Adám Aug 29 '16 at 6:07
0
\$\begingroup\$

Clojure, 53 bytes

Well, list comprehension idea from Haskell solution seems to be the shortest:

#(apply str(for[p"8549176320"b(str %):when(= p b)]p))

My original approach is 1 byte longer:

#(apply str(sort-by(zipmap"549176320"(range))(str %)))

You can see both function online here: https://ideone.com/afac5n

\$\endgroup\$
0
\$\begingroup\$

Common Lisp, 104

(lambda(n)(#1=parse-integer(sort(format()"~A"n)'string<= :key(lambda(u)(format()"~R"(#1#(string u)))))))

Ungolfed

(lambda (n)
  (parse-integer
   (sort (format nil "~A" n)
         #'string<=
         :key (lambda (u) (format nil "~R" (parse-integer (string u)))))))

Convert integer as string, sort characters using the string<= comparison while using a custom :key function which converts a given character as the English representation of the numerical value it represents. Usually I would not use a key function which does as much as this one, but it costs less in bytes than decorate/sort/undecorate.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 234 bytes

This is a direct translation of my Factor answer, just for fun.

def f(n):
 s=list(map(int,str(n)))
 return int("".join(list(map(str,list(map(lambda x:x[1],sorted(list(zip(list(map(lambda t:{0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine"}[t],s)),s)))))))))

The semantics of the evaluation of "lazy" map and zip objects is the most subtle hard-to-find-bug-inducing piece of genuine horse excrement in the universe. Sometimes, s = map(f, x) won't allow s to be used properly or at all.

\$\endgroup\$
0
\$\begingroup\$

Pyke, 14 bytes

.#uЀB`@

Try it here!

\$\endgroup\$
0
\$\begingroup\$

C, 80 bytes

Takes a string containing a number in base 10 and prints to stdio:

F(char*i){for(char*p,d,*o="8549176320";*o;++o)for(p=i;d=*p++;d-*o||putchar(d));}
\$\endgroup\$
0
\$\begingroup\$

Python 2.7.11, 67 bytes

lambda n:''.join(sorted(list(n),key=lambda s:"9487216503"[int(s)]))

Takes a string as input and outputs a string.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 74 bytes

lambda x:''.join(i[1]for i in sorted(['9487216503'[int(j)],j]for j in x))
\$\endgroup\$
  • \$\begingroup\$ You might be able to save some bytes by using a lambda \$\endgroup\$ – Daniel Jul 9 '16 at 21:09
0
\$\begingroup\$

PHP, 107 bytes

function($a){usort($a,function($a,$b){return($z=array_flip([8,5,4,9,1,7,6,3,2,0]))[$a]-$z[$b];});return$a;}

Try it online!

Uses a user-defined comparison function to adjust the sorting order.

Output

101         110
31948       84913
5544        5544
1234567890  8549176320
\$\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.