-5

Attempting the Eight Queens problem in Python (https://open.kattis.com/problems/8queens).

I've written some code which works for all input I've been able to imagine for the last hour - but the program still fails the Kattis test cases.

It's not very efficient, or well structured, but since the problem shouldn't require speed I didn't really care.

What I'm doing is checking every position, if there is a queen there - I check horizontally, vertically, and diagonally. I figured that it's probably the diagonal checking code that's wrong since the other 2 are very straightforward, but I can't figure it out...

Edit: Request to paste code in question, don't see why but sure:

Edit2: Edited code by adding counter to make sure there are 8 queens.

Edit3: Fixed last bug, code is now working!

import sys
import math

def horizontal(j, row):
    for k in range(8):
        if k == j:
            continue
        if row[k] == '*':
            return False
    return True

def vertical(rows, row , column):
    for i in range(8):
        if i == row:
            continue
        if rows[i][column] == '*':
            return False
    return True

def diagonal(rows, row, column):
    #first diagonal
    current_row = row
    current_col = column

    #go furthest up
    while True:
        if current_col == 0 or current_row == 0:
            break
        current_col-=1
        current_row-=1
    while True:
        if current_row == row and current_col == column:
            if current_col == 7 or current_row == 7:
                break
            current_col += 1
            current_row += 1
            continue
        if rows[current_row][current_col] == '*':
            return False
        if current_col == 7 or current_row == 7:
            break
        current_col += 1
        current_row += 1

    #other diagonal
    current_row = row
    current_col = column
    while True:
        if current_col == 7 or current_row == 0:
            break
        current_col+=1
        current_row-=1
    while True:
        if current_row == row and current_col == column:
            if current_col == 0 or current_row == 7:
                break
            current_col -= 1
            current_row += 1
            continue
        if rows[current_row][current_col] == '*':
            return False
        if current_col == 0 or current_row == 7:
            break
        current_col -= 1
        current_row += 1
    return True

rows = []
for i in range(8):
    rows.append(sys.stdin.readline().rstrip())

valid = True
counter = 0

#for every row:
for row in range(8):
    for column in range(8):
        if rows[row][column] == '*':
            counter += 1
            if not (horizontal(column,rows[row]) and vertical(rows, row, column) and diagonal(rows, row, column)):
                valid = False
                break

    if not valid:
        break
if valid and counter == 8:
    print("valid")
else:
    print("invalid")
ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • What's the question? Are you asking for us to code review your project and find figure out why it's not working? – Gillespie Jun 21 '17 at 15:52
  • Are all of the sample inputs passing? – Gillespie Jun 21 '17 at 15:54
  • @RPGillespie The samples are passing, as well as every other test i could imagine. Question is: Can you see any obvious flaws? Can you imagine a test case where my code brakes? – Krilliminell Jun 21 '17 at 16:08
  • StackOverflow isn't really the place for questions like this. This question is very specific to you and your code, and that doesn't really help anyone but you. I took a glance at your code and I agree that your diagonal function is very confusing and possibly has some unexpected edge cases you haven't covered. I would refactor that function and try again. – Gillespie Jun 21 '17 at 17:20
  • There are only 92 correct solutions. I would start by making sure all 92 come back as valid. If they do, it means your program is flagging invalid solutions as valid. – Gillespie Jun 21 '17 at 17:23

1 Answers1

0

You aren't checking to make sure there are exactly 8 queens on the board. Pass in an empty board and your program says it's valid.

num_queens = 0
for row in range(8):
    for column in range(8):
        if rows[row][column] == '*':
            num_queens += 1

...

if num_queens != 8:
    valid = False
Gillespie
  • 5,780
  • 3
  • 32
  • 54
  • oh lol didnt even realise that was a requirement, poorly worded from them imo.. Thanks man! – Krilliminell Jun 21 '17 at 17:44
  • @Krilliminell What happens if `valid` but not `counter == 8`? Does your program just terminate without printing anything? – Gillespie Jun 21 '17 at 18:45
  • yep haha just saw that, fixed it now! What is the deal with downvotes on this site? Why do people downvote a random question? Should I have posted differently? – Krilliminell Jun 21 '17 at 18:49
  • 2
    @Krilliminell Don't take the downvotes personally. "Find my bug" questions are frowned upon because they only help one person at a time. The goal of StackOverflow is to create a collection of questions that benefit multiple people. You are getting downvotes for a few reasons - (1) this is a "homework help"/"find my bug" type post that only benefits you, (2) you've pasted a ton of code whereas ideally you should only paste a small snippet containing the problem. Don't take it personally - just try better on the next question and answer a few questions yourself to give back to the community! – Gillespie Jun 21 '17 at 19:09
  • I totally agree with you on them not specifying the question properly. To me, a board with fewer than 8 queens isn't an invalid solution to the 8 queens problem, it's an invalid input. It'd be like asking us to make sure that there weren't 9 characters per line instead of 8, or that all of the blanks are represented by dots and not commas. That stuff isn't solution-related, it's just bad input. – Tim M. Nov 08 '18 at 01:11