21
\$\begingroup\$

Your task is it to output a number as a unary string. You get the number of a non-negative integer input in the range of 0 - 2'000'000'000.

Rules

  • You can choose any character for the digit you like. But it has to be the same everywhere and for every input.
  • Output a unary string by outputting this character N times. N is the input.
  • Input range is 0 - 2'000'000'000 (inclusive)
  • A input of 0 result in a empty string except the optional starting and ending characters.
  • You may or may not add optional starting and ending characters at the start and/or end, for example a newline character or [ and ]. If you do, all outputs (including of the input 0) must have one. This characters are different from the the character for the digit you have chosen.
  • Input integer is given as decimal, hexadecimal, octal or binary number, whatever is convenient for you.
  • You are free to use a pattern of multiple characters for a single digit. But it has to be the same pattern for all digits and for every input.
  • Digit grouping is optional. If you use it, the group size has to be constant and the separation character has to be the same everywhere.
  • Your program should finish in less than 4h on a modern desktop CPU with 4 GB of free RAM, for any valid input.
  • Output is a string or stream of characters.

Examples / test cases:

Input  ->  Output

./yourProgram 1  -> 1
./yourProgram 12 -> 111111111111
./yourProgram 0  -> 
./yourProgram 2000000000 | tr -d -c '1' | wc -c -> 2000000000
./yourProgram 32 -> 11111111111111111111111111111111

Non-golf example program:

#!/usr/bin/env python3
import sys

for i in range( int(sys.argv[1]) ):
  print("1", end='')

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

Related but they have significant differences:

\$\endgroup\$
14
  • \$\begingroup\$ Can I output a list of unary digits? \$\endgroup\$ Commented Jul 18, 2023 at 15:52
  • 2
    \$\begingroup\$ @TheThonnu I would prefer standalone programs/scripts. But gave up on that, because people don't like that for some reason. So it is ok. \$\endgroup\$ Commented Jul 18, 2023 at 16:23
  • 1
    \$\begingroup\$ @12431234123412341234123 Why are you arbitrarily overriding default output methods? generators lists definition of a list Also, if this is a clarification, it should be an edit, not buried in the comments. \$\endgroup\$ Commented Jul 18, 2023 at 23:33
  • 1
    \$\begingroup\$ In particular, this unfairly disadvantages languages like Haskell where the default string type is a lazy linked list. \$\endgroup\$ Commented Jul 18, 2023 at 23:55
  • 1
    \$\begingroup\$ I wonder which answers did actually test the runtime for the big number edge case. \$\endgroup\$
    – Philippos
    Commented Jul 19, 2023 at 8:40

44 Answers 44

11
\$\begingroup\$

Python 3, 11 bytes

'0'.__mul__

Try it online!

Note: 0 could be any other character. Function returning a string.

Python 3, 21 bytes

def f(n):print('0'*n)

Try it online!

Function which prints the string.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Very clever usage of python magic functions \$\endgroup\$
    – Cruncher
    Commented Jul 21, 2023 at 12:09
7
\$\begingroup\$

Charcoal, 1 byte

Try it online! Link is to verbose version of code. Explanation: Charcoal prints a number as a number of -, |, / or \ symbols depending on the direction of the pivot, the default being horizontal.

\$\endgroup\$
7
\$\begingroup\$

TypeScript’s Type System, 62 bytes

type U<N,L extends 1[]=[]>=L extends{length:N}?L:U<N,[...L,1]>

Try it at the TypeScript Playground!

Type definition taking a generic integer type and recursively appending 1 to a tuple type until its length is the integer type.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Unfortunately, it cannot handle more than 999 (at least at the playground) I've run into TS limitations many times in real code, so it's the first thing I've checked with a little hope that something has changed. :( \$\endgroup\$
    – Nikolay
    Commented Jul 18, 2023 at 20:08
  • 2
    \$\begingroup\$ @Nikolay Yep, that's the recursion limit for tail-recursive TS types. For non tail-recursive types it's only 50. You can make tuple types that are much longer (I want to say 9,999 elements?) so in theory you could subtract 999 and append U<999> but I can't think of a way to do that subtraction and to check if the number is too big without either A. using unary, which won't work because the number is too big; or B. implementing math based on digit lists, which sounds like hell and also way overkill for this. \$\endgroup\$ Commented Jul 19, 2023 at 1:37
6
\$\begingroup\$

Raku, 4 bytes

1 x*

Try it online!

\$\endgroup\$
6
\$\begingroup\$

Rust, 12 bytes

|a|vec![0;a]

Attempt This Online!

\$\endgroup\$
4
\$\begingroup\$

Thunno 2, 1 byte

Try it online!

Uses a space as the character.

Vyxal, 1 byte

I

Try it Online!

Same as above.

\$\endgroup\$
4
\$\begingroup\$

Lua, 21 bytes

print(('0'):rep(...))

Try it online!

\$\endgroup\$
4
\$\begingroup\$

J, 4 bytes

#&LF

Uses linefeed as the character. The large test case will not work on ATO, but 100 timex '# f 2000000000' yields an average of 0.421414 seconds.

Attempt This Online!

#&LF
#     NB. copy
 &LF  NB. bond LF as the right argument
\$\endgroup\$
4
\$\begingroup\$

Hexagony, 14 12 bytes

(}?@_.)<!>*'

Try it online!

Layed out

   ( } ?
  @ _ . )
 < ! > * '
  . . . .
   . . .

Explanation

(}? some irrelevant operations initially, then get the input

< branch, if 0 go to @ and terminate, otherwise point the IP southeast

(_ decrement the input cell and redirect the IP northeast

}*)! move the MP to the cell to the right, set that cell to 1 and print that out

_> redirect the IP back east

*' irrelevant operation, then move the MP back to the input cell

this then loops back to the branch command

\$\endgroup\$
2
  • \$\begingroup\$ Doesn't seem to work with 0. \$\endgroup\$ Commented Jul 19, 2023 at 16:19
  • 1
    \$\begingroup\$ @12431234123412341234123 Fixed it so that it works for 0 now and also saved 2 bytes in the process :) \$\endgroup\$ Commented Jul 19, 2023 at 20:30
4
\$\begingroup\$

Retina 0.8.2, 5 bytes

.+
$*

Try it online! Explanation: Outputs 1 repeated by the input count, with a trailing newline.

For Retina 1, remove the $, and then the program outputs _ repeated by the input count, without a trailing newline.

\$\endgroup\$
4
\$\begingroup\$

C# (Visual C# Interactive Compiler), 21 bytes

x=>new String('a',x);

Try it online!

My first time writing an answer here!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ -1 byte by dropping the semicolon (just move it to the footer on TIO) \$\endgroup\$ Commented Jul 21, 2023 at 18:04
  • \$\begingroup\$ @SuperStormer is that accepted? I looked through some other C# solutions, I think most finish with a semicolon. \$\endgroup\$
    – KeizerHarm
    Commented Jul 21, 2023 at 18:06
  • \$\begingroup\$ Well, this works so I would say yes. The ; doesn't appear to be part of the actual function definition, based on my limited understanding. \$\endgroup\$ Commented Jul 21, 2023 at 18:14
  • \$\begingroup\$ @SuperStormer: But can you write other code after it without a ;? Imagine you're writing a C# program, and want to use this definition as part of it instead of inlining the definition at every use-case. You need to count all the bytes necessary for the statement that defines the lambda or function, that come between other source lines of your program. (Or without actual newlines since you can put everything on one line.) \$\endgroup\$ Commented Jul 25, 2023 at 4:39
  • \$\begingroup\$ @PeterCordes Citing precedent: Should function literals be allowed when a function is asked for? \$\endgroup\$ Commented Jul 25, 2023 at 4:45
4
\$\begingroup\$

C (gcc) -O3, 24 bytes

-1 byte thanks to @12431234123412341234123

f(n){n&&puts(f)+f(n-1);}

Try it online!


C (gcc), 42 bytes

Full program, input from stdin

main(n){printf("%.*d",n,!scanf("%d",&n));}

Try it online!


C (gcc) -m32, 44 bytes

Full program, input as command line argument

*p;main(n,v){printf("%.*d",atoi(1[p=v]),0);}

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ For the recursive variant, I get a stack overflow when the input is too high. Can you avoid that? \$\endgroup\$ Commented Jul 18, 2023 at 16:38
  • \$\begingroup\$ f(n){while(n--)puts(f);} \$\endgroup\$ Commented Jul 18, 2023 at 16:41
  • 2
    \$\begingroup\$ @12431234123412341234123 if you enable optimizations gcc will recognize the tail recursion \$\endgroup\$
    – c--
    Commented Jul 18, 2023 at 16:57
3
\$\begingroup\$

><> (Fish), 10 bytes

i:?!;1-1n!

Hover over any symbol to see what it does

Try it

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Unfortunately this method of explanation is useless on my iPhone. \$\endgroup\$ Commented Jul 18, 2023 at 15:59
  • \$\begingroup\$ @noodleman you should be able to long press a symbol to see the title on mobile \$\endgroup\$ Commented Jul 18, 2023 at 16:00
  • \$\begingroup\$ It just selects all the text. \$\endgroup\$ Commented Jul 18, 2023 at 16:01
  • \$\begingroup\$ This runs at about 1 character per second on my computer (with a 3900X). Maybe it is just the online interpreter. Can it finish in the required time on a native interpreter or compiled program? \$\endgroup\$ Commented Jul 18, 2023 at 16:06
  • \$\begingroup\$ It will be a lot faster on TIO \$\endgroup\$ Commented Jul 18, 2023 at 16:08
3
\$\begingroup\$

Arturo, 15 bytes

$=>[repeat"1"&]

Try it!

\$\endgroup\$
3
\$\begingroup\$

jq, 8 bytes

"1"*.+""

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Pascal, 96 characters

program u(input,output);var i:integer;begin read(i);while i>0 do begin write('𝍷');i≔i−1 end end.

Necessary implementation characteristics: The value of maxInt must be ≥ 2000000000.

\$\endgroup\$
3
\$\begingroup\$

Alice, 15 bytes

/ M \1*.n$@9ot

Try it online!

The new line at the end of the code is required
Uses tab as the output character

/ M \1*.n$@9ot    # Full program
/ M \1*           # Reads one argument as a string and multiply it by 1, this is our loop counter
       .n$@       # Stop if the counter is down to 0
           9o     # Output a <tab>
             t    # Decrement the counter
                  # Goes back to the beginning of the line
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 2 bytes

Uses character 1.

Try it online.

Î×

Uses character 0.

Try it online.

°¦

Uses character 0 as well.

Try it online.

õú

Uses a space as character.

Try it online.

If different multiple output-characters would have been allowed, it could be 1 byte with:

Try it online.

Explanation:

$   # Push 1 and the input-integer
 ×  # Repeat the 1 the input amount of times as string
    # (which is output implicitly as result)

Î   # Push 0 and the input-integer
 ×  # Repeat the 0 the input amount of times as string
    # (which is output implicitly as result)

°   # Push 10 to the power of the (implicit) input-integer
 ¦  # Remove the leading 1 so only the 0s remain
    # (which is output implicitly as result)

õ   # Push an empty string ""
 ú  # Pad it with the (implicit) input-integer amount of leading spaces
    # (which is output implicitly as result)

∍   # Extend/shorten the (implicit) input to a length of the (implicit) input-integer
    # (which is output implicitly as result)
\$\endgroup\$
3
  • 1
    \$\begingroup\$ If multiple output-characters would have been allowed, it could be 1 byte with: it is: You are free to use a pattern of multiple characters for a single digit But it has to be the same for every input which doesn't do. \$\endgroup\$ Commented Jul 19, 2023 at 11:10
  • \$\begingroup\$ @12431234123412341234123 made a minor clarification to the explanation, but it's indeed invalid, hence the 2 byte solutions. :) \$\endgroup\$ Commented Jul 19, 2023 at 11:23
  • \$\begingroup\$ If you could use a different digit composed of multiple characters for each input, you can cheat by always output N times (except when the input is 0) the same character where N is the product of all primes between 1 and 2000000000. A digit is then M times this character where M is N/<input>. Well, if the program is fast enough which is maybe not the case for a N this large. A smaller example: Always output 30 times A. If the input is 1, a single digit has 30 times A in it, if the input is 2, a digit has 15 times A in it, if it is 3, a digit has 10 times A in it, ... \$\endgroup\$ Commented Jul 19, 2023 at 12:37
3
\$\begingroup\$

Befunge-93, 9 15 17 bytes

<,7_@#:+&

Try it online!

This program is pretty simple. It gets a number as input, then it decrements it by adding -1. -1 is the value returned when there is no input left, so I'm able to just use one & symbol to get the numbers I need and just continue adding the current value and -1 to decrement. Each time the number is decremented, the program checks if it is 0, and if it is, it quits. I did this by using a bridge (#) to skip over the stop command (@) and the go backward to the @ if the value is 0 using a horizontal if _. Previous versions of my program weren't linear, but rather 2d, so the control was taking up a lot of space. The bridge command allowed me to keep control linear. The program starts with a < to make the program go backwards, this is because the horizontal if statement _ goes right if 0, but I need it to go left, so I reversed the whole program because that's easier than reversing it's input.

\$\endgroup\$
3
\$\begingroup\$

Java (JDK), 11 bytes

"1"::repeat

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ I think that "1".repeat would be a valid answer to this \$\endgroup\$ Commented Jul 19, 2023 at 15:53
  • \$\begingroup\$ @Samathingamajig No, it has to be a function, but "1"::repeat works; a method reference instead of a lambda expression. Thanks for the tip! \$\endgroup\$ Commented Jul 19, 2023 at 20:12
3
\$\begingroup\$

x86 / x86-64 machine-code, 7 bytes, as fast as memset

Just a function, not a full program, so we only need to memset(buf, '1', n) + append a terminating 0 to make an implicit-length C-style string in the buffer the caller supplies, of size n+1 or larger.

This could be called from C in the x86-64 System V calling convention as void to_unary(char *dst, int dummy, int dummy, size_t n). Size is limited only by address-space limits.

machine code | NASM source

              ; RDI or ES:EDI = output buffer of size n
              ; RCX or ECX = n
              to_unary:
 B031           mov al, '1'
 F3AA           rep stosb
 880F           mov byte [rdi], cl    ; RCX was zeroed by rep stos
 C3             ret

stos stores and then increments, so it leaves RDI pointing after the last byte it stored. We depend on the calling convention for DF=0 (increment not decrement), as is normal for all mainstream 32 and 64-bit calling conventions.

The same machine code bytes will do the same thing in 32-bit mode.

At first I was going to use dec eax / stosb for the terminator, with 1 instead of '1' as the unary digit "character". This would be 2 bytes in 32-bit mode only. But then I realized a mov store wouldn't need a displacement in the addressing mode, and that we had cl=0.


For an explicit-length-string version using separate pointer+length, we could return the input length after filling the input buffer (also leaving a pointer to the end in RDI). This would take the same total machine-code size: push rcx to start, pop rax at the end, instead of mov [rdi], cl.


If the buffer is large and aligned, speed on typical modern CPUs, especially with the ERMSB feature, is basically as fast as typical libc memset, at least on Intel maybe not AMD.

On a typical desktop, single-core memory bandwidth is usually close to maxing out the memory controllers. (Much lower per-core bandwidth on many-core Xeons.) Slower with page faults on the first access to newly allocated RAM, but this runs about as fast as it's possible for a single thread to go (for large aligned buffers), except by playing virtual memory tricks to map a range of virtual pages to the same memsetted page of '1's. With a misaligned buffer it's still probably under a second to fill 2GB. For small n, microcode startup overhead dominates, even on CPUs with the "fast-short-rep" feature. AMD CPUs may have slower rep stos, but even storing 1 byte per clock cycle would be way faster than the 4 hour requirement needs.

\$\endgroup\$
3
  • \$\begingroup\$ Does it reserve the buffer? If not, from where do you get it? Or will it cause a Segment Fault when you run it? \$\endgroup\$ Commented Jul 21, 2023 at 9:46
  • \$\begingroup\$ @12431234: The caller passes it a pointer to a buffer for it to store the output string in. This is one of a couple normal ways for C functions to produce array output, same for assembly. (Others being to malloc new memory). If the caller passes it a bad pointer, that's a bug in the caller. I looked through Default for Code Golf: Input/Output methods but that linked answer is the only one I found that seems related to whether this is an allowed output method, but I've used it before in many other challenges where the output is an array. \$\endgroup\$ Commented Jul 21, 2023 at 12:01
  • \$\begingroup\$ I think this answer is more relevant for that: codegolf.meta.stackexchange.com/a/8511/59900 I see that this are the default Input/Output. (if you ask me, the default should only be fully runnable programs). The problem in this question is that allocating the correct amount of memory is already most of the task. When you use a 0-byte as digit, you can even mmap or calloc() enough bytes and set the address one byte after the last digit to 1 (or a different value) and don't have to set any other byte. \$\endgroup\$ Commented Jul 21, 2023 at 12:55
3
\$\begingroup\$

Bash, 13 bytes (with calling other programs)

yes|head -n$1
Explanation

yes prints lines with the content yes. head -n will filter for the first n lines, n is given with $1. The line with yes is used as digit.

Pure Bash, 29 34 bytes

for((i=$1;0<i;i--));do [;done
Explanation

The for((i=$1;0<i;i--)) will do the commands between do and done $1 times. [ is a builtin bash command that expects a test and a ], which isn't provided, so it prints a error message every time. The error message is used as digit.

I tried also this one:

$1||pwd;$1||0 $(($1-1))

Which works almost when the script is named 0 and in the current $PATH. But it fails with large inputs, so not a working solution.

Explanation

The || means, if that on the left side fails, try that on the right side instead (till the end of the line or ;). If it doesn't fail ignore the part on the right side. If there is nothing on the left side, the right is also ignored.

This tries to call program $1, i.e. the first parameter provided. Since the script is named 0, it will work with the input 0. so it calls itself without any argument. And then, when it runs without an argument, $1 will expands to nothing, which means do nothing and ignore the part right of ||.

If the parameter $1 is a number>0, it will fail to execute a program because there is no program with that name. This means a error message is printed to stderr, which we ignore, and then the right side of || is executed.

The $1||pwd; part means: If program $1 is not valid, i.e. $1 is a number above 0, it calls pwd. pwd outputs something to stdout and it shouldn't change. So we can use it as a non-changing digit. The $1||0 $(($1-1)) part means: If program $1 is not valid, call 0 / itself with the parameter $(($1-1)). $(($1-1)) means 1 subtracted from $1.

It fails with large input because it recursively calls itself and so a new process starts. But i can't create 2'000'000'000 processes on my PC.

\$\endgroup\$
3
\$\begingroup\$

jot(1), 10 bytes

jot -b1 $1

Try it online!

Outputs a stream of 1s separated by newlines. TIO times out doing the 2 billion case, but it takes just 4 minutes on my Intel Mac

$ time jot -b 1 2000000000|wc -l
 2000000000
jot -b 1 2000000000  243.40s user 0.52s system 99% cpu 4:04.24 total
wc -l  2.61s user 1.70s system 1% cpu 4:04.24 total
\$\endgroup\$
3
\$\begingroup\$

JavaScript, 15 bytes

n=>"".padEnd(n)

Try it online!

Returns the string. Uses a space as the character.

This might not be allowed, but for 9 bytes

"".padEnd

Try it online!

-1 from both thanks to @Arnauld

JavaScript, 22 bytes

n=>print("".padEnd(n))

Try it online!

Prints the string.

\$\endgroup\$
10
  • \$\begingroup\$ I think using spaces is allowed? \$\endgroup\$
    – Arnauld
    Commented Jul 18, 2023 at 17:01
  • \$\begingroup\$ @Arnauld great idea, thanks! \$\endgroup\$
    – The Thonnu
    Commented Jul 18, 2023 at 17:04
  • 1
    \$\begingroup\$ I think that "".padEnd is a valid answer itself, you don't need to wrap it \$\endgroup\$ Commented Jul 19, 2023 at 15:56
  • 1
    \$\begingroup\$ @IsmaelMiguel idk, I'll ask in TNB \$\endgroup\$
    – The Thonnu
    Commented Jul 22, 2023 at 2:29
  • 1
    \$\begingroup\$ @IsmaelMiguel see here. It seems that just "".padEnd is invalid. \$\endgroup\$
    – The Thonnu
    Commented Jul 22, 2023 at 4:40
3
\$\begingroup\$

Haskell, 18 16 bytes

-2 bytes thanks to Bubbler

(`replicate`'a')

Attempt This Online!

On my machine, it finished in 48.68 seconds and had a max RSS of 4656 kb, well under the time and memory limits.

\$\endgroup\$
1
  • \$\begingroup\$ (`replicate`'a') works at 16 bytes. \$\endgroup\$
    – Bubbler
    Commented Jul 24, 2023 at 7:25
2
\$\begingroup\$

C (gcc), 49 bytes

Full program, takes 1 argument

main(a,v)int**v;{for(a=atoi(v[1]);a--;puts(*v));}

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ puts(v) may work as well (not very reliable but reliable enough. It depends on the ASLR. Most runs works => good enough). \$\endgroup\$ Commented Jul 18, 2023 at 17:24
  • \$\begingroup\$ I originally had f(n){while(n--)puts(f);} but then saw that function was already submitted, so I pivoted to this. puts(v) will vary based on the input/run, so I decided to go with puts(*v). Maybe I was too strict with the rules on this one. \$\endgroup\$
    – Saladin
    Commented Jul 18, 2023 at 18:24
  • \$\begingroup\$ Leave it up there, I don't care. I'll also note that f(n){for(;n--;)puts(f);) is the same length. \$\endgroup\$
    – Saladin
    Commented Jul 18, 2023 at 19:08
  • 1
    \$\begingroup\$ If you creative about the input specification, this will also work: main(a,v)int**v;{for(a=*v[1];a--;puts(*v));} On my machine, to input 0 use ./a.out '' '' '' '', To input 32 ./a.out ' ' '' '' ''. 8224 ./a.out ' ' '' '' '' for 2097184 use ./a.out ' ' ' ' '' '' for 8192 ./a.out '' ' ' '' ''. Not sure how to escape '\x01' in bash but that is a problem of bash not the program. \$\endgroup\$ Commented Jul 19, 2023 at 10:30
2
\$\begingroup\$

Swift, 31 bytes

{.init(repeating:"1",count:$0)}

Try it online! A bit more verbose than some, but hopefully clear enough.

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

Ruby, 9 bytes

->n{?1*n}

Attempt This Online!

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

As a whole program:

F# (.NET Core), 66 bytes

[<EntryPoint>]let m a=[for _ in 1..(int(Seq.head a))->printf"1"];0

Try it online!


As a function:

F# (.NET Core), 33 bytes

fun a->[for _ in 1..a->printf"1"]

Try it online!

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

[Matlab], 9 bytes

ones(1,n)

ones generates mxn matrixes of 1s


[Matlab], 16 bytes

second version upon remarks in the comments

s=@(n) ones(1,n)

anonymous function that generates mxn matrixes of 1s

\$\endgroup\$
3
  • \$\begingroup\$ Taking input through a variable (like n) isn't allowed. You'll need to turn this into a function or full program. \$\endgroup\$
    – rydwolf
    Commented Jul 19, 2023 at 14:14
  • \$\begingroup\$ i intended it as 'n' is already defined in the workspace and this is a command window call \$\endgroup\$
    – Ferro Luca
    Commented Jul 19, 2023 at 14:17
  • \$\begingroup\$ Although that makes sense for some languages like Matlab, it's unfortunately still disallowed. \$\endgroup\$
    – rydwolf
    Commented Jul 19, 2023 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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