I don't know really how to explain it, but I need to write a Python program that should output this:
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
Can someone help me and explain me how to do that?
Thank you :)
CodePudding user response:
It looks like this program needs to run like this:
output first number
output second number
output first-second numbers
output third number
output fourth number
output third-fourth numbers
output first to fourth numbers
(same for five to eight)
output all eight
Have a think about the pattern here, and see if you can solve it!
CodePudding user response:
I realize that the problem has already been solved and an answer has been selected, but a more generic algorithm came to mind, which I feel compelled to share. We repeatedly concatenate previous patterns (delimited by "-"), and this concatenation happens 1x for each perfect power of 2 that our iteration number is divisible by. Therefore, with some bit checking and stack manipulation, we can very easily abstract the problem away into a solution that will work with any size input, any character set, etc., and will even behave well on non-power-of-two sized inputs.
def print_patterns(alphabet, delimiter="-"):
stack = []
def push(pattern):
print(pattern)
stack.append(pattern)
def pop():
pat1 = stack.pop()
pat2 = stack.pop()
return f"{pat2}{delimiter}{pat1}"
for index, char in enumerate(alphabet, 1):
push(char)
for bit in reversed(bin(index)):
if bit != '0':
break
push(pop())
Example output:
>>> print_patterns("12345678")
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
And an edge case:
>>> print_patterns("abcdef", "*")
a
b
a*b
c
d
c*d
a*b*c*d
e
f
e*f
CodePudding user response:
Here is an implementation of @fanfly's comment, using a recursive generator:
def f(s):
if len(s) >= 2:
m = (len(s) 1)//2
yield from f(s[:m])
yield from f(s[m:])
yield '-'.join(iter(s))
Testing:
>>> print('\n'.join( f('abcd') ))
a
b
a-b
c
d
c-d
a-b-c-d
>>> print('\n'.join( f(''.join(map(str, range(1,9)))) ))
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
CodePudding user response:
Ok one solution would be the following:
lst = list(range(1,9))
def func(l):
lst_str = list(map(str, lst))
for i in l:
print(i)
for dvd in (2, 4, 8):
if i % dvd == 0:
print("-".join(lst_str[i-dvd:i]))
func(lst)
OUTPUT
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
this would fail for other series, so maybe instead of the element itself in the sequence we want to check its position in the list. For example:
lst = list(range(9,17))
def func(l):
lst_str = list(map(str, lst))
for n, i in enumerate(l):
print(i)
n = 1
for dvd in (2, 4, 8):
if n % dvd == 0:
print("-".join(lst_str[n-dvd:n]))
func(lst)
OUTPUT
9
10
9-10
11
12
11-12
9-10-11-12
13
14
13-14
15
16
15-16
13-14-15-16
9-10-11-12-13-14-15-16
You can extend this to more power of two, so instead of iterating just for (2, 4, 8)
you could use [2**n for n in range(1,max_exp 1)]
where max_exp
is an input of your choice