In this task, we creating a function called highsum. It looks at a list of strings and sums up all the numerical characters. We then return the location of the element of the list with the highest value.
For example given list highestSum([“jx72i9r”, “9ch37#r2”, “8rgku3op8”]).
We then must find [17, 21,19] which is all the numerical values added up. Because 21 is the highest value we need the function to return 1 because that is the location of 9ch37#r2 in the list.
This is what I have so far:-
def highestSum(stringList):
number= 0
for xinlist in stringList:
print(xinlist)
for yoflist in xinlist:
print (yoflist)
if yoflist in "1234567890":
number+=int(yoflist)
print(number)
The first for loop cycles through each element while the second for loop cycles through each character in the elements. My accumulator variable work but the problem is I don't know how to let it know when it moves on to a new element.
Another example highestSum([“90gw1xy3”, “12432”, “hfkvbd2”, “*&hdj!4”])
this would return 0 as it as the highest sum of digit characters.
Homemade version
Basically, we gather turn each element in the given list to there digits sum. So like [18,21,19]. Then pair this with original list using zip(). Then use .index() in order to get the corresponding index.
hilarious one-liner
def highestSum(stringList):
return stringList.index({k:v for k,v in zip([sum(list(map(int,[character for character in stringEx if character.isdigit()]))) for stringEx in stringList],stringList)}[max(summed)])
List comprehension & dict comprehension
def highestSum(stringList):
summed = [sum(list(map(int,[character for character in stringEx if character.isdigit()]))) for stringEx in stringList]
highest = max(summed)
pair = {k:v for k,v in zip(summed,stringList)}
return stringList.index(pair[highest])
print(highestSum(["jx72i9r", "9ch37#r2", "8rgku3op8"]))
Easier to understand for the human eye.
def highestSum(stringList):
summed = []
for stringEx in stringList:
gathered = []
for character in stringEx:
if character.isdigit():
gathered.append(character)
gathered = sum(list(map(int,gathered)))
summed.append(gathered)
highest = max(summed)
pair = {}
for k,v in zip(summed,stringList):
pair[k] = v
return stringList.index(pair[highest])
print(highestSum(["jx72i9r", "9ch37#r2", "8rgku3op8"]))
output
1
I have modified your code. Look at this solution. You need a condition to for the highest number in the list and a variable to keep track of its index. See solution below:
def highestSum(stringList):
index = 0
highestValue = 0
for xinlist in stringList:
number= 0
for yoflist in xinlist:
if yoflist in "1234567890":
number+=int(yoflist)
if number > highestValue:
index = stringList.index(xinlist)
highestValue = number
print(index)
stringList = ['jx72i9r', '9ch37#r2', '8rgku3op8']
highestSum(stringList)
def highestSum(stringList):
res = list()
for xinlist in stringList:
number = 0
for yoflist in xinlist:
if yoflist in "1234567890":
number += int(yoflist)
res.append(number)
# find the max position form the accumulator
maxNumPos = 0
for i in range(len(res)):
if res[i] > res[maxNumPos]:
maxNumPos = i
print(maxNumPos)
highestSum(['90gw1xy3', '12432', 'hfkvbd2', '*&hdj!4'])
I'll use list comprehension, maybe it's difficult to read.
code:
x = ["jx72i9r", "9ch37#r2", "8rgku3op8"]
x_to_int = [sum([int(char) for char in s if char.isdigit()]) for s in x]
print(x_to_int.index(max(x_to_int)))
result:
1
I'm working on an assignment for my CIS class in python. We have to code a Sudoku checker. In a 9x9 board we obviously have to check each row, col and 3x3 square for duplicates. I'm a little stuck on the idea of how to check the numbers by a 3x3 square. Below is my code for checking each row and col, if someone could help me a little with an outline or an approach just something for checking each 3x3 square that would be amazing!
self.columns = [ ]
for col in range(9):
col_tiles = [ ]
self.columns.append(col_tiles)
for row in range(9):
col_tiles.append(self.tiles[row][col])
self.squares = [ ]
for col in range(1, 10, 3):
for row in range(1, 10, 3):
square_tiles = [ ]
self.squares.append(square_tiles)
for x in range(3):
for y in range(3):
square_tiles.append(self.tiles[x][y])
This assumes you have the freedom to read the data and structure how you want. We want a set of unique values 1-9 for each row/column/3x3 grid, so one way is to either use a set or a list comparison (we'll use set here to make it cleaner). If we create a set equal to the numbers from 1 to 9, we have a point against which we can compare all of our other groups. Assume a structure like this (from here):
In [1]: r1 = [9,3,2,5,4,8,1,7,6]
In [2]: r2 = [1,8,7,9,2,6,5,4,3]
In [3]: r3 = [5,4,6,3,7,1,2,8,9]
# Continues....
Where each row represents a full row of data. Now lets create a section of that data that represents the first three rows, pull out one grid and compare the contents to our set:
In [4]: sec1 = [r1, r2, r3]
In [5]: nums = set(range(1, 10))
In [6]: nums == set(n for row in sec1 for n in row[:3])
Out[6]: True
This iterates over the first three rows and returns the first three elements in each of those rows. To get a better visual, here is the equivalent for-loop code to make it a bit easier to decipher:
result = set()
for row in sec1:
for n in row[:3]:
result.add(n)
Since our set of numbers includes everything from 1-9, we know it is valid. To move to the second, we range the row[:3] to row[3:6] (and row[6:9] after that). You'll then need to handle this for the next two sections as well. I'll leave it to you as to how to wrap this in a more dynamic structure (note the multiples of three), but hopefully this will get you started :)
Whenever you're having trouble coming up with an algorithm, just ask yourself: "How would I solve this manually, if the only way I could be given the problem was by a computer".
In other words, if I asked you to check the top left 3x3 grid, your eyes would just go to the top left corner and add up numbers. But if I said, check the top left 3x3 grid, and didn't actually give you the board, you'd say, "OK, give me the top left 3x3 grid".
And I'd say "How?"
And you'd say, "Imagine the tiles are numbered by rows and columns. I want the tiles in spots (0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), and (2,2)"
Does that help?
Here's what I would do: create 3 dictionaries, one for the rows, one for the columns, and one for the 3x3 squares.
while you loop through each element in the sudoku puzzle, keep track of your row and column (trivial), and use if statements to keep track of which 3x3 square you're in (a bit more involved)
then just send each element to the corresponding row, column, and 3x3 square dictionary, and compare at the end.
This way you only need to inspect each element once.
EDIT: also, set will probably be useful
This function will do. "sample" gives the randomness, so every time you run this you will get a different one.
from random import sample
def generate_sudoku_checker():
random_list = sample([1,2,3,4,5,6,7,8,9],9)
random_list = random_list + random_list[:9]
for i in range(3):
for j in range(3):
print(random_list[i+j*3:i+j*3+9])
Here is my solution to this :
Funtion:
def check_sudoku(lis):
n = len(lis)
digit = 1 #start from one
while (digit<=n):
i=0
while i<n: # go through each row and column
row_count=0
column_count=0
j=0
while j < n: # for each entry in the row / column
if lis[i][j] == digit: # check row count
row_count = row_count+1
if lis[j][i]== digit :
column_count = column_count+1
j=j+1
if row_count !=1 or column_count!=1:
return False
i=i+1 # next row/column
digit = digit+1 #next digit
return True
Late to the party but this worked for me:
def insert_sudoku():
puzzle = []
for i in range(9):
print("You've entered", len(puzzle), "rows so far")
row = input("Enter a row")
if len(row) < 9:
print("Not enough numbers on this row")
return insert_sudoku()
elif len(row) > 9:
print("Too many numbers. Try again!")
return insert_sudoku()
try:
row = [int(dig) for dig in row]
puzzle.append(row)
except:
print("Whoops, looks like you didn't enter only numbers somewhere. Try again!")
return insert_sudoku()
validate_entries(puzzle)
def validate_entries(puzzle):
check = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b1, b2, b3, b4, b5, b6, b7, b8, b9 = [], [], [], [], [], [], [], [], []
for i in range(9):
z = []
for x in range(9):
z.append(puzzle[i][x])
puzzle.append(z)
for i in range(3):
b1 += (puzzle[i][:3])
b4 += (puzzle[i][3:6])
b7 += (puzzle[i][6:])
for i in range(3,6):
b2 += (puzzle[i][:3])
b5 += (puzzle[i][3:6])
b8 += (puzzle[i][6:])
for i in range(6,9):
b3 += (puzzle[i][:3])
b6 += (puzzle[i][3:6])
b9 += (puzzle[i][6:])
puzzle.append(b1)
puzzle.append(b2)
puzzle.append(b3)
puzzle.append(b4)
puzzle.append(b5)
puzzle.append(b6)
puzzle.append(b7)
puzzle.append(b8)
puzzle.append(b9)
for iter in puzzle:
if sorted(iter) != check:
print("No")
return
print("Yes")
insert_sudoku()
Inspired by this article
EDIT: Indentation might be off from copy + pasting the code.
What my answer adds is the use of a list comprehension to extract the tiles from the board.
"""
# good
board=[
[2,9,5,7,4,3,8,6,1],
[4,3,1,8,6,5,9,2,7],
[8,7,6,1,9,2,5,4,3],
[3,8,7,4,5,9,2,1,6],
[6,1,2,3,8,7,4,9,5],
[5,4,9,2,1,6,7,3,8],
[7,6,3,5,2,4,1,8,9],
[9,2,8,6,7,1,3,5,4],
[1,5,4,9,3,8,6,7,2]
]
"""
# bad
board = [
[1,9,5,7,4,3,8,6,2],
[4,3,1,8,6,5,9,2,7],
[8,7,6,1,9,2,5,4,3],
[3,8,7,4,5,9,2,1,6],
[6,1,2,3,8,7,4,9,5],
[5,4,9,2,1,6,7,3,8],
[7,6,3,5,2,4,1,8,9],
[9,2,8,6,7,1,3,5,4],
[2,5,4,9,3,8,6,7,1]
]
def check(l):
# each digit 1-9 should occur once
for n in range(1,10):
try:
l.index(n)
except ValueError:
return False
return True
# check the rows
for row in board:
print(check(row))
# check the columns
for column in [ [ board[r][c] for r in range(9) ] for c in range(9) ]:
print(check(column))
# check the tiles
for tile in [[board[r][c] for r in range(row, row + 3) for c in range(col, col + 3)] for row in range(0, 9, 3) for col in range(0, 9, 3)]:
print(check(tile))
This is my solution. I also want to confirm the time and space complexity of this code:
"""
Sample input 1:
295743861
431865927
876192543
387459216
612387495
549216738
763524189
928671354
154938672
Output: YES!
Sample input 2
195743862
431865927
876192543
387459216
612387495
549216738
763524189
928671354
254938671
Output: NOPE!!
"""
##################Solution############################################
def get_input():
#Get the input in form of strings and convert into list
print("Enter the board here: ")
lines = []
while True:
line = input()
if line:
lines.append(line)
else:
break
final = [(list(i)) for i in lines]
return final
def row_check(board):
# row check function which will be used in other two functions as well
text = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
x = True
for row in board:
if sorted(row) == text:
x = True
else:
x = False
return x
def col_check(board):
# Getting the list of 9 lists containing column elements
i = 0
j = 0
cols = [[], [], [], [], [], [], [], [], []]
for j in range(0, 9):
for i in range(0, 9):
cols[j].append(board[i][j])
return (row_check(cols))
def tile_check(board):
#Getting the list of 9 lists converting each tile of 3x3 into 9 element list
lst =[[],[],[],[],[],[],[],[],[]]
i = 0
j = 0
k = 0
while k<9:
for r in range(i,i+3):
for c in range(j, j+3):
lst[k].append(board[r][c])
j = j +3
k = k +1
if j == 9:
j = 0
i = i+3
return (row_check(lst))
#main program
c = get_input()
if row_check(c) and col_check(c) and tile_check(c):
print("YES!")
else:
print("NOPE!!")