21
\$\begingroup\$

Given an ordered list of numbers (possibly with leading zeros), arrange the numbers vertically, then let all zeros drop all the way to the bottom and all overhangs drop to the bottom-most open slot. Output the resulting integers, removing leading zeros.

Worked Example

Say we were given the following as input:

['0000312941295', '239124000124581598', '32852353800451258', '10235923505185190', '1491359102149']

First we arrange it vertically:

0000312941295
239124000124581598
32852353800451258
10235923505185190
1491359102149

Then, column by column, drop the zeros "through" the other numbers so they rest on the bottom and "push" the other numbers up. This would result in the first couple steps being as follows:

2000312941295
339124000124581598
12852353800451258
10235923505185190
0491359102149
^

2300312941295
329124000124581598
14852353800451258
10235923505185190
0091359102149
 ^

2390312941295
328124000124581598
14252353800451258
10935923505185190
0001359102149
  ^

...

2391312941295
328524538124581598
14232323525451258
10915991001185190
0000350000049
                ^

Next, drop all overhangs as if gravity is pulling them down like sand.

2391312941295
3285245381245 1598
14232323525458258
10915991001181190
00003500000495
             ^

2391312941295
3285245381245  598
14232323525458158
10915991001181290
000035000004951
              ^

...

2391312941295
3285245381245
14232323525458159
10915991001181258
000035000004951908
                 ^

Finally, output these numbers, removing leading zeros. For our worked example, output:

[2391312941295, 3285245381245, 14232323525458159, 10915991001181258, 35000004951908]

For another example, suppose input of [1234000,12345678,1234,12340608,12341234].

1234000
12345678
1234
12340608
12341234

Drop the zeros:

1234  
12345678
1234163
12340208
12340004

Drop the remaining overhanging digits:

1234  
1234567
12341638
12340208
12340004

Output is [1234, 1234567, 12341638, 12340208, 12340004].

Rules

  • The input may contain leading zeros. The output must not contain leading zeros.
  • If applicable, you can assume that the input/output will fit in your language's native Integer type.
  • The input and output can be given by any convenient method.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
\$\endgroup\$
  • 2
    \$\begingroup\$ May we assume that the output numbers will not exceed our language's precision? (JS rounds 14232323525458159 to 14232323525458160) \$\endgroup\$ – ETHproductions Feb 21 '18 at 15:54
  • \$\begingroup\$ @ETHproductions I think that's a PPCG default. \$\endgroup\$ – Erik the Outgolfer Feb 21 '18 at 15:55
  • \$\begingroup\$ and all overhangs drop to the bottom-most open slot was a good fix to my broken challenge :). \$\endgroup\$ – Magic Octopus Urn Feb 21 '18 at 15:58
  • 1
    \$\begingroup\$ @PeterCordes Yes, the input may contain leading zeros, so it should be able to handle that. I imagine for most languages, that means take input as a string. \$\endgroup\$ – AdmBorkBork Feb 22 '18 at 21:24
  • 1
    \$\begingroup\$ @PeterCordes Input and output doesn't necessarily need to be in base-10 (that's in the allowed default I/O methods), so long as using a different base doesn't trivialize the task (that's a standard loophole). Secondly, I guess I didn't specify that the leading zeros must be removed completely, though that was the intent. I'm going to rule that replacing the zeros with spaces is not allowed, as outputting . 1234 is very different than outputting 1234. \$\endgroup\$ – AdmBorkBork Feb 23 '18 at 13:43

11 Answers 11

10
\$\begingroup\$

Jelly, 8 bytes

Z¬Þ€UZṚḌ

Try it online!

How it works

Z¬Þ€UZṚḌ  Main link. Argument: M (2D array / matrix)

Z         Zip; transpose M by reading columns as rows.
 ¬Þ€      Sort each row of the transpose by logical NOT, pushing 0's to the end.
    U     Upend; reverse all sorted rows of the transpose.
     Z    Zip again, restoring rows from columns. Overhangs rise to the top.
      Ṛ   Reverse the order of the rows.
       Ḍ  Decimal; convert the rows from base 10 to integer.
\$\endgroup\$
  • 4
    \$\begingroup\$ WHAT? As I was reading the question I was thinking: "Finally, there's no way someone can pull off less than 20 bytes for this". Madness \$\endgroup\$ – Cruncher Feb 21 '18 at 23:46
  • 1
    \$\begingroup\$ Sort each row of the transpose by logical NOT, pushing 0's to the end. Is this guaranteed to be a stable sort? \$\endgroup\$ – Cruncher Feb 21 '18 at 23:48
  • 1
    \$\begingroup\$ Yes, Jelly uses Python's sorted, which is guaranteed to be stable. \$\endgroup\$ – Dennis Feb 22 '18 at 0:13
  • \$\begingroup\$ I kind of like this commutative looking version: ṚZẸÞ€ZṚḌ :) \$\endgroup\$ – Jonathan Allan Feb 25 '18 at 23:26
5
\$\begingroup\$

05AB1E, 11 bytes

ζεð†R0†R}øï

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Never seen used before, nice one. \$\endgroup\$ – Magic Octopus Urn Feb 21 '18 at 15:59
4
\$\begingroup\$

Husk, 12 bytes

md↔TmoÖ±miT↔

Try it online!

Explanation

md↔Tm(Ö±mi)T↔  -- input as list of strings, example: ["103","32","258"]
            ↔  -- reverse: ["258","32","103"]
           T   -- transpose: ["231","520","83"]
    m(    )    -- with each line do (example with "520")
        mi     -- | convert each char to digit: [5,2,0]
      Ö±       -- | sort by signum (stable): [0,5,2]
               -- : [[2,3,1],[0,5,2],[8,3]]
   T           -- transpose: [[2,0,8],[3,5,3],[1,2]]
  ↔            -- reverse: [[1,2],[3,5,3],[2,0,8]]%
md             -- convert each to integer: [12,353,208]
\$\endgroup\$
4
\$\begingroup\$

Python 2, 118 bytes

lambda l:[int(''.join(z))for z in zip(*map(lambda*a:['']*a.count(None)+[e for e in a if'0'<e]+['0']*a.count('0'),*l))]

Try it online!

Ungolfed version

def f(list_):
 max_len = max(len(x) for x in list_)
 transposed_list = zip(*[list(row)+(max_len-len(row))*[None] for row in list_])
 weighted_list = [['']*column.count(None)+[cell for cell in column if cell != '0' and cell != None]+['0']*column.count('0') for column in transposed_list]
 return [int(''.join(row)) for row in zip(*weighted_list)]

The first two lines are equivalent to map(lambda*a...), the default behaviour if for map to fill with Nones if one list is shorter than the other.
e>'0' is equivalent to cell != '0' and cell != None, because if it is any digit (1~9) it will have a higher codepoint, and (any) string is higher than None.

\$\endgroup\$
  • \$\begingroup\$ Care to post an ungolfed version of this? \$\endgroup\$ – Peter Cordes Feb 22 '18 at 21:30
  • \$\begingroup\$ @PeterCordes added the ungolfed version and a short explanation for some obscure points \$\endgroup\$ – Rod Feb 22 '18 at 22:22
2
\$\begingroup\$

Pyth, 11 bytes

iRT_C_M!DMC

Try it online!

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

Retina 0.8.2, 95 92 bytes

m(+`^((.)*)(.+)(¶(?<-2>.)*)(?(2)_)$
$1$4$3
+`^((.)*)0(.*¶(?>(?<-2>.)*))([^0])
$1$4${3}0
^0+

Try it online! Explanation: The first stage drops the overhanging digits as this makes it easier (edit: even easier for a 3-byte saving) for the second stage to drop the zeros. The third stage then removes leading zeros.

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

Ruby, 104 bytes

->a{a.map{|x|x.ljust(99).chars}.transpose.map{|x|x.sort_by{|x|x<?1?x:?!}}.transpose.map{|x|x.join.to_i}}

Try it online!

Explanation

->a{
  a.map{|x|x.ljust(99).chars}  # Fill spaces to make this rectangular
    .transpose.map{|x|
       x.sort_by{|x|x<?1?x:?!} # Treat all chars but " 1" as ! (see ascii table)
    }.transpose.map{|x|x.join.to_i} # Convert back to numbers
                       # note: if no leading 0s, eval x*'' , doesn't work here
}
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Unicode), 26 bytesSBCS

Anonymous tacit prefix function taking a character matrix as argument and returning a list of numbers.

⍎⍤1∘⍉' 0'(∩∘⊃,~,∩∘⊃∘⌽)⍤1⍨⍉

Try it online!

 transpose the input (as we need to work on the columns)

' 0'()⍤1⍨ apply the following tacit function to each row (sub-array of tensor rank 1) with ' 0' as right argument ( swaps the arguments) :

 intersection of the row and
 and
 the first of ' 0'
 (i.e. row∩' '; all the spaces from each row)

, followed by…

~ the set difference
 (i.e. row~' 0'; the row but without spaces and zeros)

, followed by…

 intersection of the row and
 and
 the first
 of
 the reversed ' 0'
 (i.e. row∩'0'; all the zeros from each row)

⍎⍤1 evaluate each row (sub-array of tensor rank 1)
 of
 the transpose of that (i.e. each column; the now modified input rows)

\$\endgroup\$
  • \$\begingroup\$ The parenthesised bit is clever. It took me a while to understand the intention there, though I know what individual squiggles do. Once I understood it, it's easy to beat: ⍎⍤1∘⍉{⍵[⍋3|2×' 0'⍳⍵]}⍤1∘⍉ (⎕io←0) It may be golfable further, e.g. I didn't explore dyadic \$\endgroup\$ – ngn Feb 22 '18 at 13:10
  • \$\begingroup\$ actually, the above is shorter as a complete program (not a train): ⍎⍤1⍉{⍵[⍋3|2×' 0'⍳⍵]}⍤1⍉⎕ \$\endgroup\$ – ngn Feb 22 '18 at 13:14
  • \$\begingroup\$ @ngn Such a different method merits own post. The pre- and post-processing is obvious. \$\endgroup\$ – Adám Feb 22 '18 at 13:17
1
\$\begingroup\$

Perl 5, -p0 77 bytes

Old style counting: 79 bytes (+2 for p0)

Give input as lines on STDIN without final newline (otherwise everything is seen as overhang and the final newline rises to the top as the input string crashes down). E.g.:

0000312941295
239124000124581598
32852353800451258
10235923505185190
1491359102149

It was a bit tricky to get the overhang dropping and the 0 dropping into one regex

#!/usr/bin/perl -p0
s/^.{@{+}}\K((0)|.+$)(.*
.{@{+}})((?(2)[1-9]|$))/$4$3$1/m while/|/g;s/^0+//mg

Try it online!

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

Ruby, 203 bytes

->a{t=->b{b[0].zip(*b[1..-1])}
m=a.map{|s|s.size}.max
a.map!{|s|(s+" "*m)[0...m].chars}
a=t[a].map{|c|c.size.times{|i|" 0"[c[i]]&&(c.slice!(i)==?0?c.push(?0):c.unshift(" "))}
c}
t[a].map{|r|r.join.to_i}}

Try it online!

A lambda accepting an array of strings and returning an array of ints. I feel like I'm missing something; this feels enormous :/

->a{
  t = -> b { b[0].zip(*b[1..-1]) }     # t is a lambda that transposes 2D arrays
  m = a.map{ |s| s.size }.max          # m is the maximum input string length
  a.map!{ |s| (s+" "*m)[0...m].chars } # Right-pad every string to the same length
  a = t[a].map{ |c|                    # Transpose a, and for every row (column)
    c.size.times{ |i|                  # For every character in the column
      " 0"[c[i]] && (                  # If the character is 0 or space
        c.slice!(i) == ?0 ?            # Remove it from the column, and if it was 0,
          c.push(?0) :                 # Push a 0 to the end (bottom) of the column, else
          c.unshift(" ")               # Add a space to the top of the column
      )
    }
    c
  }
  t[a].map{ |r| r.join.to_i }          # Transpose a back, and parse each row to int
}
\$\endgroup\$
  • \$\begingroup\$ I outgolfed this (for now) \$\endgroup\$ – Unihedron Feb 22 '18 at 9:25
  • \$\begingroup\$ @Unihedron Wow, you beat me by 50%. You've got my +1 for sure. \$\endgroup\$ – benj2240 Feb 22 '18 at 19:51
0
\$\begingroup\$

APL (Dyalog Classic), 24 23 22 bytes

⍎⍤1⍉{⍵[⍒⌈9÷⍨⎕d⍳⍵]}⍤1⍉⎕

Try it online!

based on Adam's solution

\$\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.