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 at 19:22
  • 3
    Plz some comments for down-votes... – mdahmoune Nov 29 at 10:24
  • Downvotes don't require leaving comments for a reason. There is nothing that can be improved about this challenge. – user202729 Nov 29 at 14:55
  • So don't worry about it. – user202729 Nov 29 at 15:13
  • Are the outputs required to be in the same order as the input? – Mnemonic Nov 29 at 20:01

17 Answers 17

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.

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 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 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 at 10:50
  • Right, that's annoying… – Fatalize Nov 29 at 11:35

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 :))

Haskell, 68 bytes

n!('1':'0':x)|n-2<length x=10:(n-1)!x
n!(s:x)=read[s]:(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

  • 1
    -3 bytes: drop space between : [c and 'x' else and 10 for – mdahmoune Nov 28 at 19:12
  • @mdahmoune Thanks for noticing, I have a hard time remembering what can be squished together. – Gigaflop Nov 28 at 19:16
  • 8
    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 at 19:21
  • There are some exceptions such as <number>e, <letter><number>, f'. – user202729 Nov 29 at 5:37
  • 3
    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 at 6:47

Haskell, 98 bytes

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 _=[[]]

Try it online or test all!

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 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 at 18:59
  • 1
    We can coerce everything to integers for +1 byte. – Arnauld Nov 28 at 18:59
  • 59 bytes eval(`[${s}]`.replace('1,0',10)) – guest271314 Nov 29 at 7:49
  • @guest271314 Thanks! Nice catch. – Arnauld Nov 29 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!

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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