# Unzip some numbers

Your task is to create a program or function that generates a zipper with a length of 10 lines. Each line of the zipper is represented by two dashes --:

--
--
--
--
--
--
--
--
--
--


The program/function will take a percentage (divisible by 10) as input, and the output will be the zipper "unzipped" (dashes separated) from the top by the percentage, revealing the 1-indexed, lowest level repeated 2 times, with all prior levels repeated 4, 6, 8, ...etc. times, while keeping the bottom of the zipper centered.

### Examples

>>10%
-11-
--
--
--
--
--
--
--
--
--

>>50%
-1111111111-
-22222222-
-333333-
-4444-
-55-
--
--
--
--
--

>>100%
-11111111111111111111-
-222222222222222222-
-3333333333333333-
-44444444444444-
-555555555555-
-6666666666-
-77777777-
-888888-
-9999-
-10-


The input (percentage) can be formatted however you like (50%, .5, 50, 5 [zero implied], etc), and it will always be in the range of 0 to 100 and divisible by 10. The spacing in the examples must be preserved in your output.

• May the input ever be 0%? Are we allowed to take the input divided by 10? e.g. instead of 50%, get 5? Commented Jul 12, 2016 at 16:28
• The input (percentage) can be formatted however you like (50%, .5, 50), Can it be just 5? Commented Jul 12, 2016 at 16:33
• @DrGreenEggsandIronMan the input can be 0%, and you can take the input in the most convenient format. Commented Jul 12, 2016 at 16:35
• @LuisMendo, yes, I'll edit that into the question, thanks. Commented Jul 12, 2016 at 16:36
• Is a leading line break instead of a trailing one accepted? Is absolute padding accepted? Commented Jul 12, 2016 at 22:11

# Python 2 - 184151 146 Bytes

def r(n):
n/=10
for i in range(1,11):
if n<0:print"%s--"%p
elif i>9:print" %s-10-"%p
else:p=" "*~-i;print"%s-%s-"%(p,i*2*n);n-=1


The last number kinda messed with me a little. I might be able to remove the second if statement if I look at it later.

EDIT: Thx to mbomb007 for removing 3 bytes. Thanks to charredgrass for the formatting tips to help remove lots and lots of bytes! :-D Thanks to TheBikingViking for helping with yet another two bytes!

• Use i>9 instead of i==10 and remove the space in range(1, 11). Commented Jul 12, 2016 at 16:54
• Small tip for golfing in python: you cut down on a lot of bytes from whitespace by compressing your statements onto one line. For example the last 3 lines can become p=" "*(i-1);print"%s-%s-"%(p,str(i)*2*n);n-=1. Commented Jul 12, 2016 at 17:15
• thanks ! That helps a lot with this one and I'll definitely keep that in mind in future golfing Commented Jul 12, 2016 at 17:45
• You can shave off 2 bytes by replacing (i-1) in the last line with ~-i. This takes advantage of operator precedence and the fact that a bit flip followed by a negation is the same as subtracting 1. Commented Jul 12, 2016 at 17:58
• What is the point of using range(1,11) and then (i-1)? Commented Jul 12, 2016 at 20:18

# Python 2, 74 bytes

n=input()
x=0
exec"print' '*x+'-'+x+1*(n-x<<1-x/9)+'-';x=min(x+1,n);"*10


Saved two bytes by exec-ifying a loop, thanks to Dennis.

EDIT: I took a slightly different approach and saved two more bytes.

• You can save 2 bytes using string formatting by replacing '-'+x+1*(n-x<<1-x/9)+'-' in the exec loop with '-%s-'%x+1*(n-x<<1-x/9). Commented Jul 12, 2016 at 22:51
• Nope, I’d need parens around the x+1*(n-x<<1-x/9).
– lynn
Commented Jul 13, 2016 at 19:25

## PowerShell v2+, 130120116 110 bytes

param($n)$i=0;10..1|%{" "*$i+(("-"+("$($i+1)"*([math]::Max($n-10+$_,0))*2)),"-10")[$n-$_-eq9]+"-";$i+=$i-ne$n}


Edit 1 - Golfed 10 bytes by eliminating $x variable and slightly redoing how the string is formulated. Edit 2 - Golfed another 4 bytes by redoing how input happens and by redoing how $i is calculated each loop.
Edit 3 - Saved 6 bytes by OP allowing input as 0..10, so no need to divide by 10.

Surprisingly difficult!

Takes input as 1,5, etc., stored in $n. Sets helper $i variable (one of the very rare times that a variable needs to be initialized to 0 in PowerShell), and then starts a loop from 10 to 1.

Each iteration, we set start our string with a number of spaces equal to $i, followed by a pseudo-ternary (... , ...)[]. Inside the pseudo-ternary, we select a string of either - with a number of digits (the higher of $n-10+$_ or 0, multiplied by 2), or the string -10 -- the selection is based on whether we're at the 10th iteration and our input was 100. We concatenate that with a final -. That resultant string is placed onto the pipeline. Finally, we increment $i, and this was really tricky. We wound up using a binary-cast-to-int trick to only increment $i up until it reaches $n, and then keeping it at the same value thereafter. This ensures we've reached the "end" of the zipper indentation at the appropriate level.

Once the loop has finished, the resultant strings are all accumulated on the pipeline and output is implicit.

### Examples

PS C:\Tools\Scripts\golfing> .\unzip-some-numbers.ps1 70
-11111111111111-
-222222222222-
-3333333333-
-44444444-
-555555-
-6666-
-77-
--
--
--

PS C:\Tools\Scripts\golfing> .\unzip-some-numbers.ps1 100
-11111111111111111111-
-222222222222222222-
-3333333333333333-
-44444444444444-
-555555555555-
-6666666666-
-77777777-
-888888-
-9999-
-10-


# Pyth, 37 34 bytes

=h/QTjm+*;thS,dQj<*d20eS,0y-Qd"--"ST
=h/QTjm+*;thS,dQj*d/y-Qdld"--"ST


Test suite.

# Python, 95 84 bytes

I wasn't aware lambdas were legal, thanks @Dr Green Eggs and Iron Man

lambda p:'\n'.join(' '*min(p,l)+'-'+(2-(l==9))*(p-l)*str(l+1)+'-'for l in range(10))

• Hey, great first answer! You can move it out of a list comprehension to save 2 bytes, join can take a generator directly. Commented Jul 12, 2016 at 20:14
• You can do a lambda instead of printing. With Morgan's suggestion: lambda p:'\n'.join(' '*min(p,l)+'-'+(2-(l==9))*(p-l)*str(l+1)+'-'for l in range(10)) (84 bytes) Commented Jul 12, 2016 at 20:17

# MATL, 4841 35 bytes

0:9"@GhX<Z"45h@QVG@-E@8>-OhX>Y"h45h


Try it online!

# Ruby, 74 bytes

Uses the implied-zero format specified in the question, so 40% is f[4] if the anonymous function is assigned to f. If a full percentage is needed, +6 bytes for n/=10;

Try it online!

->n{10.times{|i|puts' '*[i,n].min+"-#{i>8?10:(i+1).to_s*2*(n-i)if i<n}-"}}


# Python 3, 98, 90, 87, 85 bytes.

Takes the number already divided by 10. I can probably remove some of the parens, but this is pretty closed to fully golfed.

lambda n:'\n'.join(' '*min(i,n)+'-%s-'%(str(i+1)*(n>i>8or(n-i)*2))for i in range(10))


f n=unlines[[[1..y]>>" ",take(2*(n-y))$cycle$show$y+1]>>=(++"-")|y<-min n<$>[0..9]]

• What's ++"-"? Commented Jul 12, 2016 at 21:29

# Javascript es7, 105 bytes

A=>[...Array(10)].map((a,i)=>' '.repeat((d=A<i)?A:i)+('-'+(i+1+'').repeat(d?0:i<9?2*(A-i):1)+'-')).join



call with

f=A=>[...Array(10)].map((a,i)=>' '.repeat((d=A<i)?A:i)+('-'+(i+1+'').repeat(d?0:i<9?2*(A-i):1)+'-')).join


f(10)
f(5)
f(0)

• The program/function ... - not snippet Commented Jul 12, 2016 at 22:32
• If you replace the \n with an actual newline, you can save a byte. Commented Jul 13, 2016 at 0:03
• @Titus What are you talking about? This "snippet" is a function. Commented Jul 13, 2016 at 0:36
• ah right. ES7, I forgot. Commented Jul 13, 2016 at 0:51
• @MamaFunRoll I had that, but couldn't wrap in "" and do .length so I wasn't 100% confident I was in the clear - I'll add it in :) Commented Jul 13, 2016 at 12:37

# Python 2.7, 113108 77 bytes

n=input()
for x in range(0,10):
v=str(x+1)*(n-x)2
if x
n>89:v='10'
print' '*min(x,n)+'-'+v+'-'

First time playing golf. Gonna keep going, try to get it <100.
Assumes input is 1-10.

Edit: Used some tricks from @LeakyNun 's answer (thanks), then crunched it a bit further and got... basically the same answer :/ Didn't know about the int string conversion, and 2 - boolean let me get rid of the if statement, which let me get rid of the whole v variable. Very cool.

My version:

n=input()
for x in range(10):print' '*min(x,n)+'-'+x+1*(n-x)*(2-(x>8))+'-'

• Nice answer, and welcome to the site! You could take off 9 bytes by changing the indentation level to 1 space, instead of 4. Commented Jul 13, 2016 at 20:15
• Actually, you could make this even shorter with this: n=input(); for x in range(0,10):print' '*min(x,n)+'-'+('10'if x*n>89 else str(x+1)*(n-x)*2)+'-' Commented Jul 13, 2016 at 20:23

# Python 2, 81 bytes

n=input()/10
for i in range(10):print(' '*min(i,n)+'-'+2*(n-i)/-~(i>8)*i+1+'-')


Ideone it!

# Python 2.7, 1109995 91 bytes:

G=input();i=1;exec"print' '*[~-i,G][i>G]+'-%s-'%[i*(2*-~G-i*2),'10'][(i>9)*G>9];i+=1;"*10


A full program that takes input by an integer in the inclusive range [1,10], where 10 means 100% and 1 means 10%. Can probably be golfed down a bit more.

# PHP 5.3, 92 91 bytes

<?for(;$i<10;$i++)echo'
'.str_pad('-'.str_repeat($i+1,$n>9&&$i>8?:($n-$i)*2).'-',22,' ',2);  • for PHP 5.3 with register_globals=1 and short_open_tags=1 (and error_reporting=0) call in cli with php-cgi -f <filename> n=<number> • number from 0 to 10 • to call in web browser with <scriptpath>?n=<number>: prepend <pre> • for 4.0.1 < PHP < 5.3: replace ?: with ?1: (+1) • for PHP>=5.4: replace the first $n with ($n=$_GET[n]) (+11)

ungolfed as a function (any PHP>=4.0.1)

function unzip($n) //$n from 0 to 10
{
for($i=0;$i<10;$i++) //$i = line number -1
$s.=' '.str_pad( // pad the result of the following on both sides '-'. // prepend '-' str_repeat($i+1,                // print line number
($n>9&&$i>8 ? 1             // in tenth line, if $n is 10: once : ($n-$i)*2) // else 2*($n-$i) times ).'-' // append '-' , 22,' ', STR_PAD_BOTH); // pad to 22 width with SPC on both sides return$s;
}


test suite

echo'<table border=1><tr>';
for($i=0;$i<11;$i++)echo'<th>',$i*10,'%</th>';
echo'</tr><tr>';
for($i=0;$i<11;$i++)echo'<td><pre>', unzip($i), '</pre></td>';
echo '</table>';


Now this is new to me: PHP beats JavaScript.
This approach is golfed to the min, I think.

• STR_PAD_BOTH What is this, K&R C? Do we #define things in PHP too? :-)
– cat
Commented Jul 13, 2016 at 1:47
• @cat: yup, there are real defines in PHP. but only static; not like in C. Commented Jul 13, 2016 at 2:02

# Julia, 73 bytes

x->join([" "^min(x,a)*"-$("$(a+1)"^(x>a?a>8?1:2(x-a):0))-"for a=0:9],'
')


First Julia answer! Tips are appreciated.

Try it online!

• oh right lol :P Commented Jul 13, 2016 at 14:08

# Perl, 122 bytes

$k=<>;for(my$i=0;$i++<10;){$s="-"."$i"x($k/10-$i+1);$p=length $s;$l=$l>$p?$l:$p;printf "%${l}s%s\n",$s,scalar reverse \$s}


## Common Lisp (Lispworks), 314 bytes

(defun f()(let((s(string(read))))(let((n(/(parse-integer(subseq s 0(1-(length s))))10)))(if(> n 0)(progn(dotimes(r n)(progn(dotimes(c r)#1=(format t" "))(format t"-")(if(=(1+ r)10)(format t"10")(dotimes(j(* 2(- n r)))(format t"~S"(1+ r))))(format t"-~%")))(dotimes(d(- 10 n))(dotimes(c n)#1#)(format t"--~%")))))))


ungolded:

    (defun f ()
(let ((n (/ (parse-integer (subseq s 0 (1- (length s)))) 10)))
(if (> n 0)
(progn
(dotimes (r n)
(progn
(dotimes (c r)
(format t " "))
(format t "-")
(if (= (1+ r) 10)
(format t "10")
(dotimes (j (* 2 (- n r)))
(format t "~S" (1+ r))))
(format t "-~%")))
(dotimes (d (- 10 n))
(dotimes (c n)
(format t " "))
(format t "--~%")))))))


Usage:

    CL-USER 2515 > (f)
10%
-11-
--
--
--
--
--
--
--
--
--
NIL

CL-USER 2516 > (f)
50%
-1111111111-
-22222222-
-333333-
-4444-
-55-
--
--
--
--
--
NIL

CL-USER 2517 > (f)
100%
-11111111111111111111-
-222222222222222222-
-3333333333333333-
-44444444444444-
-555555555555-
-6666666666-
-77777777-
-888888-
-9999-
-10-
NIL


## APL, 46 bytes

{↑(⍳10){(''↑⍨1-⍺⌊a+1),1⌽'--',⍵⍴⍕⍺}¨10↑2×⌽⍳a←⍵}
`

The argument should be given as the percentage divided by 10 (that is: a simple integer, in the range [0,10]).