Reputation: 83
I want to draw a normal terminal grid in python or you can just print the numbers in a snake and ladder way. The bottom line will be 1 to 10 in order, the line above that should 11 to 20 but in reverse order and continue this till 100. How can I achieve this using Python? A scalable solution to this would be much appreciated. Thanks.
EDIT : Ok, I came up with this solution. Is there any other way to achieve it. Maybe a more pythonic way or with less time and space complexity?
numbers = [i+1 for i in range(100)]
numbers = numbers[::-1]
levels = [i for i in numbers[::-10]]
is_reversed = False
for level in levels:
if is_reversed:
for number in reversed(numbers[level-1:level+9]):
print('{:4}'.format(number), end='')
else:
for number in numbers[level-1:level+9]:
print('{:4}'.format(number), end='')
is_reversed = not is_reversed
print()
Upvotes: 2
Views: 5078
Reputation: 21
Here i is from 99 to 0 (both inclusive), the code is printing (i + 1) i.e. from 100 to 1
i // 10 will return identical value for 10 consecutive number. Based on weather this value is odd or even, the order of printing is decided.
Here i is from 99 to 0, i.e. descending order. So to print in reverse order, we need to jump with -10 for first column. for second column we need to jump with -9. However for second column the i is also reduced by 1. So we should jump with -8. Here -8 = -10 + 2 in generic way "jump = -10 + 2 (j th column)" Here column number j is from 0 to 9. It is remainder when we divide i with 10.
This is how, we get reverse order at alternate row
def snake_ladder():
for i in range(99, -1, -1):
if (i // 10) % 2 == 0:
print("{0:4d}".format(i - 10 + 2 * (10 - (i % 10))), end=" ")
else:
print("{0:4d}".format(i + 1), end=" ")
if i % 10 == 0:
print("\r")
if __name__ == "__main__":
snake_ladder()
output :
100 99 98 97 96 95 94 93 92 91
81 82 83 84 85 86 87 88 89 90
80 79 78 77 76 75 74 73 72 71
61 62 63 64 65 66 67 68 69 70
60 59 58 57 56 55 54 53 52 51
41 42 43 44 45 46 47 48 49 50
40 39 38 37 36 35 34 33 32 31
21 22 23 24 25 26 27 28 29 30
20 19 18 17 16 15 14 13 12 11
1 2 3 4 5 6 7 8 9 10
Upvotes: 2
Reputation: 1922
The below uses a list comprehension to first make the list, then a second to reverse every other row. The key was the good ol' modulo %
.
rows = [[f'{(n+1) + (i*10):4}' for n in range(10)] for i in range(10)]
rows = reversed([reversed(rows[i]) if i%2 else rows[i] for i in range(len(rows))])
for row in rows:
print(' | '.join(row))
Result:
100 | 99 | 98 | 97 | 96 | 95 | 94 | 93 | 92 | 91
81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90
80 | 79 | 78 | 77 | 76 | 75 | 74 | 73 | 72 | 71
61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70
60 | 59 | 58 | 57 | 56 | 55 | 54 | 53 | 52 | 51
41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50
40 | 39 | 38 | 37 | 36 | 35 | 34 | 33 | 32 | 31
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30
20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
A recent performance test showed me that enumerate
is more performant than using range
and indexing. That changes the second line to look like:
rows = reversed([reversed(row) if i%2 else row for i, row in enumerate(rows)])
Upvotes: 3
Reputation: 1427
for x in range(1, 101): # 1 - 100
print ("%03d" % (101 - x,), end = " | ") # make all numbers 3 digits
if x % 10 == 0: # every ten line output a new line
print()
Output
100 | 099 | 098 | 097 | 096 | 095 | 094 | 093 | 092 | 091 |
090 | 089 | 088 | 087 | 086 | 085 | 084 | 083 | 082 | 081 |
080 | 079 | 078 | 077 | 076 | 075 | 074 | 073 | 072 | 071 |
070 | 069 | 068 | 067 | 066 | 065 | 064 | 063 | 062 | 061 |
060 | 059 | 058 | 057 | 056 | 055 | 054 | 053 | 052 | 051 |
050 | 049 | 048 | 047 | 046 | 045 | 044 | 043 | 042 | 041 |
040 | 039 | 038 | 037 | 036 | 035 | 034 | 033 | 032 | 031 |
030 | 029 | 028 | 027 | 026 | 025 | 024 | 023 | 022 | 021 |
020 | 019 | 018 | 017 | 016 | 015 | 014 | 013 | 012 | 011 |
010 | 009 | 008 | 007 | 006 | 005 | 004 | 003 | 002 | 001 |
Upvotes: 1