-1

The objective is to parse the output of an ill-behaving program which concatenates a list of numbers, e.g., 3, 4, 5, into a string "345", without any non-number separating the numbers. I also know that the list is sorted in ascending order.

I came up with the following solution which reconstructs the list from a string:

a = '3456781015203040'
numlist = []

numlist.append(int(a[0]))

i = 1
while True:
    j = 1
    while True:
        if int(a[i:i+j]) <= numlist[-1]:
            j = j + 1
        else:
            numlist.append(int(a[i:i+j]))
            i = i + j
            break
    if i >= len(a):
        break

This works, but I have a feeling that the solution reflects too much the fact that I have been trained in Pascal, decades ago. Is there a better or more pythonic way to do it?

I am aware that the problem is ill-posed, i.e., I could start with '34' as the initial element and get a different solution (or possibly end up with remaining trailing numeral characters which don't form the next element of the list).

peterlin
  • 127
  • 1
  • 4
  • 1
    It is ill-posed as you said. Actually, not only the choice of initial element affect the result, every element can affect the result. In your example, parsing `a` can get [3, 4, 5..], but can also be [3, 45, 67,...] – JenkinsY Jul 05 '17 at 09:30

2 Answers2

1

This finds solutions for all possible initial number lengths:

a = '3456781015203040'

def numbers(a,n):
    current_num, i = 0, 0
    while True:
        while i+n <= len(a) and int(a[i:i+n]) <= current_num:
            n += 1
        if i+n <= len(a):
            current_num = int(a[i:i+n])
            yield current_num
            i += n
        else:
            return

for n in range(1,len(a)):
    l = list(numbers(a,n))
    # print only solutions that use up all digits of a
    if ''.join(map(str,l)) == a:
         print(l)
[3, 4, 5, 6, 7, 8, 10, 15, 20, 30, 40]
[34, 56, 78, 101, 520, 3040]
[34567, 81015, 203040]
Błotosmętek
  • 12,717
  • 19
  • 29
0

little modification which allows to parse "7000000000001" data and give the best output (max list size)

a = 30000001
def numbers(a,n):
    current_num, i = 0, 0
    while True:
        while i+n <= len(a) and int(a[i:i+n]) <= current_num:n += 1
        if i+2*n>len(a):current_num = int(a[i:]);yield current_num; return
        elif i+n <= len(a):current_num = int(a[i:i+n]);yield current_num;i += n
        else: return
        print(current_num)
for n in range(1,len(a)):
    l = list(numbers(a,n))
    if "".join(map(str,l)) == a:print (l)