Home > OS >  How do i make the program print specific letters in this specific format i give to it?
How do i make the program print specific letters in this specific format i give to it?

Time:12-07

so i need to code a program which, for example if given the input 3[a]2[b], prints "aaabb" or when given 3[ab]2[c],prints "abababcc"(basicly prints that amount of that letter in the given order). i tried to use a for loop to iterate the first given input and then detect "[" letters in it so it'll know that to repeatedly print but i don't know how i can make it also understand where that string ends also this is where i could get it to,which probably isnt too useful:

string=input()
string=string[::-1]
bulundu=6
for i in string:
    if i!="]":
        if i!="[":
            lst.append(i)
        if i=="[":
            break

CodePudding user response:

The approach I took is to remove the brackets, split the items into a list, then walk the list, and if the item is a number, add that many repeats of the next item to the result for output:

import re

data = "3[a]2[b]"
# Remove brackets and convert to a list
data = re.sub(r'[\[\]]', ' ', data).split()

result = []
for i, item in enumerate(data):
  # If item is a number, print that many of the next item
  if item.isdigit():
    result.append(data[i 1] * int(item))

print(''.join(result))
# aaabb

CodePudding user response:

A different approach, inspired by Subbu's use of re.findall. This approach finds all 'pairs' of numbers and letters using match groups, then multiplies them to produce the required text:

import re

data = "3[a]2[b]"

matches = re.findall('(\d )\[([a-zA-Z] )\]',data)
# [(3, 'a'), (2, 'b')]
for x in matches:
    print(x[1] * int(x[0]), end='')
    #aaabb

CodePudding user response:

This will help you

first get the numbers and alphabets from the given string as a list.

iterate the both the numbers and alphabets list and do the number and string multiplication operation.

import re
st = '5[a]2[b]'

# regex to get only numbers
num = re.findall('\d ',st)

# regex to get only alphabets
ss = re.findall('[a-zA-Z] ',st)
fin= ''

for a, b in zip(num,ss):
    fin = fin   int(a)*b

print(fin)

output:

aaaaabb

CodePudding user response:

Lenghty and documented version using NO regex but simple string and list manipulation:

  • first split the input into parts that are numbers and texts
  • then recombinate them again
  • I opted to document with inline comments

This could be done like so:

# testcases are tuples of input and correct result
testcases = [ ("3[a]2[b]","aaabb"), 
              ("3[ab]2[c]","abababcc"), 
              ("5[12]6[c]","1212121212cccccc"), 
              ("22[a]","a"*22)]

# now we use our algo for all those testcases
for inp,res in testcases:

    split_inp = []   # list that takes the splitted values of the input
    num = 0          # accumulator variable for more-then-1-digit numbers
    in_text = False  # bool that tells us if we are currently collecting letters

    # go over all letters : O(n)
    for c in inp:

        # when a [ is reached our num is complete and we need to store it
        # we collect all further letters until next ] in a list that we
        # add at the end of your split_inp
        if c == "[":
            split_inp.append(num)    # add the completed number 
            num = 0                  # and reset it to 0
            in_text = True           # now in text
            split_inp.append([])     # add a list to collect letters

        # done collecting letters 
        elif c == "]":
            in_text = False          # no longer collecting, convert letters
            split_inp[-1] = ''.join(split_inp[-1]) # to text


        # between [ and ] ... simply add letter to list at end
        elif in_text:
            split_inp[-1].append(c) # add letter

        # currently collecting numbers
        else:
            num *= 10      # increase current number by factor 10
            num  = int(c)  # add newest number
    
    print(repr(inp), split_inp, sep="\n")  # debugging output for parsing part

    # now we need to build the string from our parsed data
    amount = 0
    result = []  # intermediate list to join ['aaa','bb']

    # iterate the list, if int remember it, it text, build composite
    for part in split_inp:
        if isinstance(part, int):
            amount = part
        else:
            result.append(part*amount)

    # join the parts 
    result = ''.join(result)


    # check if all worked out
    if result == res:
        print("CORRECT:  ", result   "\n")
    else:
        print (f"INCORRECT:  should be '{res}' but is '{result}'\n")
        

Result:

'3[a]2[b]'
[3, 'a', 2, 'b']
CORRECT:   aaabb

'3[ab]2[c]'
[3, 'ab', 2, 'c']
CORRECT:   abababcc

'5[12]6[c]'
[5, '12', 6, 'c']
CORRECT:   1212121212cccccc

'22[a]'
[22, 'a']
CORRECT:   aaaaaaaaaaaaaaaaaaaaaa

This will also handle cases of '5[12]' wich some of the other solutions wont.

CodePudding user response:

You can capture both the number of repetitions n and the pattern to repeat v in one go using the described pattern. This essentially matches any sequence of digits - which is the first group we need to capture, reason why \d is between brackets (..) - followed by a [, followed by anything - this anything is the second pattern of interest, hence it is between backets (...) - which is then followed by a ]. findall will find all these matches in the passed line, then the first match - the number - will be cast to an int and used as a multiplier for the string pattern. The list of int(n) * v is then joined with an empty space. Malformed patterns may throw exceptions or return nothing.

Anyway, in code:

import re

pattern = re.compile("(\d )\[(.*?)\]")

def func(x): return "".join([v*int(n) for n,v in pattern.findall(x)])

print(func("3[a]2[b]"))
print(func("3[ab]2[c]"))

OUTPUT

aaabb
abababcc

FOLLOW UP

Another solution which achieves the same result, without using regular expression (ok, not nice at all, I get it...):

def func(s): return "".join([int(x[0])*x[1] for x in map(lambda x:x.split("["), s.split("]")) if len(x) == 2])
  • Related