# Split Mark's marks

## Challenge

Mark is a student who receives his N marks in a concatenated way in a one single line.

The challenge is to separate his marks, knowing that each mark can only be 0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10.

## Input

N natural number and one line.

## Output

A set of natural numbers.

## Example

N, One line------------------> Set of marks
3, '843'---------------------> [8, 4, 3]
1, '0'-----------------------> [0]
2, '1010'--------------------> [10,10]
3, '1010'--------------------> [1,0,10] or [10,1,0]
4, '1010'--------------------> [1,0,1,0]
9, '23104441070'-------------> [2, 3, 10, 4, 4, 4, 10, 7, 0]
12,'499102102121103'---------> [4, 9, 9, 10, 2, 10, 2, 1, 2, 1, 10, 3]
5, '71061'-------------------> [7, 1, 0, 6, 1]
11,'476565010684'------------> [4, 7, 6, 5, 6, 5, 0, 10, 6, 8, 4]
4, '1306'--------------------> [1, 3, 0, 6]
9, '51026221084'-------------> [5, 10, 2, 6, 2, 2, 10, 8, 4]
14,'851089085685524'---------> [8, 5, 10, 8, 9, 0, 8, 5, 6, 8, 5, 5, 2, 4]
11,'110840867780'------------> [1, 10, 8, 4, 0, 8, 6, 7, 7, 8, 0]
9, '4359893510'--------------> [4, 3, 5, 9, 8, 9, 3, 5, 10]
7, '99153710'----------------> [9, 9, 1, 5, 3, 7, 10]
14,'886171092313495'---------> [8, 8, 6, 1, 7, 10, 9, 2, 3, 1, 3, 4, 9, 5]
2, '44'----------------------> [4, 4]
4, '9386'--------------------> [9, 3, 8, 6]


## Rules

• When several outputs are possible give only one output.
• Only mark of value 10 is on two decimal, others are on one decimal.
• The input and output can be given in any convenient format
• No need to handle invalid input
• Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
• If possible, please include a link to an online testing environment so other people can try out your code!
• Standard loopholes are forbidden.
• This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
• Here's a Python snippet I used to get the n, 'string' pairs from the copypasted example text block: spl = [item.split('-')[0] for item in text.split('\n')] – Gigaflop Nov 28 '18 at 19:22
• Plz some comments for down-votes... – mdahmoune Nov 29 '18 at 10:24
• So don't worry about it. – user202729 Nov 29 '18 at 15:13
• Are the outputs required to be in the same order as the input? – Mnemonic Nov 29 '18 at 20:01

# Brachylog, 23 21 bytes

-2 bytes thanks to Fatalize

h~c.{ịℕ≤10&ịṫ?∧}ᵛ&t~l


Try it online!

The input is a pair [Line, N].

This is my first Brachylog program, so there is probably a lot room for improvement.

It is very slow when the length of the line > 7.

Explanation:

h~c.{ịℕ≤10&ịṫ?∧}ᵛ&t~l
h                         The first element in the input
~c                       is formed by concatenating
.                      the elements in the output array
.{         ∧}ᵛ     AND For every element in the output array holds that
ị                      The element converted to an integer
ℕ                       is a natural number
≤10                    and less than or equal to 10
&ịṫ?              and it has no leading zeroes (*)
&t   AND The second element of the input
~l     is the length of the output


(*) ịṫ? checks that there are no leading zeroes. It converts the string to integer and then back to string and compares to the original string.

• You don't need to input the number as a string, just use an integer. This alleviates the need for all those ị and for the leading zero check: h~c.{ℕ≤10}ᵛ&t~l. This is probably slower though as deconcatenation on integers must work even for unknown integers through constraints, which makes it inefficient. – Fatalize Nov 29 '18 at 7:46
• (Also note that using h and t to get the first/last element is more efficient than using ∋ for both (which in most programs will not even work)). – Fatalize Nov 29 '18 at 7:47
• @Fatalize I understood that the input line can contain leading zeroes, so it would not be possible to use an integer as the input. – fergusq Nov 29 '18 at 10:50
• Right, that's annoying… – Fatalize Nov 29 '18 at 11:35

# Perl 6, 25 bytes

->\a,\b{b~~/(10|.)**{a}/}


Try it online!

Anonymous code block that takes a number and a string and returns as a Match object.

### Explanation:

->\a,\b{                }  # Anonymous code block taking params a and b
b~~/           /   # Match using b
(10|.)           # 10 or a single digit
**{a}      # Exactly a times, being greedy


# Python 3, 47 bytes

lambda s,n:[*s.replace(b'\1\0',b'\n',len(s)-n)]


Try it online!

Takes the "one line" as a bytestring with raw bytes \x00 - \x09. If it's not acceptable:

# Python 3, 56 bytes

lambda s,n:[x-48for x in s.replace(b'10',b':',len(s)-n)]


Try it online!

Takes "one line" as bytestring.

# V, 17, 12 bytes

\ÓòÀGjí1“î…0


Try it online!

I was content with 17 bytes, but than 05AB1E came along with 13, and I couldn't let a challenge go unanswered. :D

\Ó                      " Put each character on it's own line
ò                     " Recursively (repeat until an error happens)...
ÀG                   "   Go to the "n"th line
j                  "   Move down a line (this will error if there are exactly "n" lines)
í                 "   Remove...
1                "     a '1'
<0x93>          "     START THE MATCH HERE
î         "     a newline
<0x85>   "     END THE MATCH HERE
0    "     a '0'


Hexdump:

00000000: 5cd3 f2c0 476a ed31 93ee 8530            \...Gj.1...0


Alternate solution:

\ÓòÀGjç1î0/J


Unfortunately, this replaces 10 with 1 0

# Ruby, 57 bytes

->n,m{m.sub!"10",?A while m[n];m.chars.map{|c|c.to_i 16}}


Try it online!

This may turn out to be not the golfiest approach, but it looks like a fun idea to temporarily substitute 10 for a hex A, which incidentally is also a high mark (if we consider A-F grading system :))

n!('1':'0':x)|n-2<length x=10:(n-1)!x
n!_=[]


Try it online!

Greedily take 10s as long as there are more digits than marks remaining.

# JavaScript, 57 52 bytes

n=>g=s=>s[n]?g(s.replace(x=10,x)):[...s].map(eval)


Try It Online

# Python 3, 71 68 59 bytes

down another 9 bytes thanks to ovs.

lambda n,s:[int(c,11)for c in s.replace('10','a',len(s)-n)]


Try it online!

I was iniitially trying to use str.partition() recursively, but using replace smacked me in the face not too long after. Can anyone improve on this?

Also, here's a TIO link that I used to make the test cases into something more copy/pasteable

• -3 bytes: drop space between : [c and 'x' else and 10 for – mdahmoune Nov 28 '18 at 19:12
• @mdahmoune Thanks for noticing, I have a hard time remembering what can be squished together. – Gigaflop Nov 28 '18 at 19:16
• General rule of thumb: Basically anything except for two letters can be squished together. If you get a syntax error, add random spaces until it works :) – Quintec Nov 28 '18 at 19:21
• There are some exceptions such as <number>e, <letter><number>, f'. – user202729 Nov 29 '18 at 5:37
• 59 bytes by replacing 10 with a and reading each character as a base 11 int: lambda n,s:[int(c,11)for c in s.replace('10','a',len(s)-n)]. – ovs Nov 29 '18 at 6:47

n!x=[y|y<-s x,y==take n y]!!0
s('1':'0':x)=do y<-s x;[1:0:y,10:y]
s(x:y)=(read[x]:)<$>s y s _=[[]]  ## Explanation The function s does all possible splits, for example: "1010" becomes [[1,0,1,0],[10,1,0],[1,0,10],[10,10]], note how the longest splits end up at the beginning (because 1:0:y comes before 10:y). With that in mind, we can take all these values and filter the ys out where y == take n y which keeps also splits that are shorter than required. For example with 4 we leave the list the same [[1,0,1,0],[10,1,0],[1,0,10],[10,10]]. Now we can just get the first element in that list because the inputs will always be valid (eg. 5!"1010" would give [1,0,1,0] too, but we don't need to handle it). Note: I somehow miscounted.. y==take n y is the same length as length y==n :S # Perl 5-plF, 39 bytes $a=<>;$_="@F";s/1 0/10/ while$a-1<y/ //


Try it online!

# Clean, 128 bytes

import StdEnv
@[]=[[]]
@['10':t]=[u++v\\u<-[[10],[1,0]],v<- @t];@[h:t]=[[digitToInt h:v]\\v<- @t]
?n l=hd[e\\e<- @l|length e==n]


Try it online!

# 05AB1E, 13 bytes

.œsù.ΔïTÝÃJ¹Q


Try it online! or as a Test Suite

Explanation

.œ              # partitions of the first input
sù            # of a length equal to the second input
.Δ          # find the first partition that returns true when:
ï         # each element is converted to integer
TÝÃ      # and only numbers in [0 ... 10] are kept
J     # then join it together
¹Q   # and compare it to the first input for equality


# JavaScript (Babel Node),  70 69  59 bytes

Takes input as (n)(line).

n=>s=>(a=s.match(/10|./g)).flatMap(x=>x>9&&!a[--n]?[1,0]:x)


Try it online!

### Commented

n => s =>                       // given n and s
(a = s.match(/10|./g))        // split s into marks; a '1' followed by a '0' is always
// interpreted as '10'
.flatMap(x =>                 // for each mark x:
x > 9 &&                    //   if x = '10',
!a[--n] ?                   //   then decrement n; if a[n] is undefined:
[1, 0]                    //     yield [1, 0]
:                           //   else:
x                         //     yield the mark unchanged
)                             // end of flatMap()


# JavaScript (ES6),  64  59 bytes

Saved 5 bytes thanks to @guest271314

Takes input as (n)(line).

n=>g=([...s])=>1/s[n]?g(eval([${s}].replace('1,0',10))):s  Try it online! ### Commented n => // main function, taking n g = ([...s]) => // g = recursive function, taking s // (which is either a string or an array) 1 / s[n] ? // if s[n] is defined (i.e. we have too many marks): g( // do a recursive call to g: eval( // build a new array by evaluating ... [${s}]              //       ... the string representation of s[] where the
.replace('1,0', 10)   //       first occurrence of '1,0' is replaced with '10'
)                       //     end of eval()
)                         //   end of recursive call
:                           // else:
s                         //   return s

• Why the output for N=3 and line='1010' is with mixed types [ 1, 0, '10' ]? – mdahmoune Nov 28 '18 at 18:57
• s.match() returns an array of strings but a "10" may be split into [1,0] (2 integers) in the callback function of flatMap(). – Arnauld Nov 28 '18 at 18:59
• We can coerce everything to integers for +1 byte. – Arnauld Nov 28 '18 at 18:59
• 59 bytes eval([\${s}].replace('1,0',10)) – guest271314 Nov 29 '18 at 7:49
• @guest271314 Thanks! Nice catch. – Arnauld Nov 29 '18 at 8:22

# Java (OpenJDK 8), 78 bytes

A nice one-liner using the streams API.

(n,l)->l.join(":",l.split("10",l.length()-n+1)).chars().map(i->i-48).toArray()


Try it online!

How it works

(n,l)->                     // Lambda function taking int and string
l.join(":",               // Join the following array with colons
l.split("10",           // Split the original string on "10"...
l.length()-n+1))      // But limit the parts to the difference between the length
// and expected length, to only remove  required number of 10s
.chars()                  // Convert to an intstream of codepoints
.map(i->i-48)             // Remove 48 to get the numeric value of each codepoint
.toArray()                // Return an int array


# R, 63 bytes

While the length of the string is larger than n, substitute the next 10 you reach for a ":" (the ASCII character after 9). Then split into numbers by taking the ASCII value of each char in the string.

function(n,x){while(nchar(x)>n)x=sub(10,":",x);utf8ToInt(x)-48}


Try it online!

# Red, 91 bytes

func[n s][while[n < length? s][replace s"10""a"]foreach c s[prin[either c =#"a"[10][c]""]]]


Try it online!

# Jelly, 18 bytes

Ḍ⁵⁻ƊƝr1ŒpS‘⁼ɗƇḢk⁸Ḍ


Try it online!