. Д ■I* . 11 .( в ) MK-*- 2 Я 7j I2.( ) Л4Ж f ' " ~l I ..... лН* ^)i7 13.(0 > ад<«4" ■tH (0)|*Л ■ <B)I JÎ-.J} (C)l:Vl .1 -»■¿¿.to. <e>'/fí (С)Л? (0)19. 1 "4^^.. (M8 (8)16 (С)«Л 18 (D)l5»/3 • f*10 ’ WAíec*,- 15 .(Й ) &АВСФ ■ <"6 ¥У1Ш& . (A)24 (“Ив (C)72 (D)96 16, C )»,’*/—<A>f» (B)5
понятно что есть более толковые инструменты, но для VBA достаточно понимания уровня бейсик/паскаль и при записи макроса позырить какой получился код.
я в студенческие годы как-то делал в экселе решалку для судоку. бесполезная херня, но навыки написания впоследствии пригодились уже в работе.
Проходит по диапазонам, проверяя наличие искомой цифры, ищет, куда можно вставить, и по новой - для следующей цифры?
в общем сделал так: массив 9х9 забил 511 во все неизвестные (двоичное 111 111 111), в известных единичка только в одном бите (например если в клетке изначально 5, то Sud(Row,Col)=(000 010 000)=2^(5-1)=16 )
For Each cell In Field
If cell.Value = "" Then Sud(cell.Row - 5, cell.Column - 1) = 511 Else Sud(cell.Row - 5, cell.Column - 1) = 2 ^ (cell.Value - 1)
cell.Font.ColorIndex = 1
Next cell
потом каждую проверяем "если в том же ряду Х, то такой цифры быть здесь не может, гасим соотв.единичку"
prohodresult = 0
For Each cell In Field
If cell.Value = "" Then
If Lonenum(Sud(cell.Row - 5, cell.Column - 1)) 0 Then cell.Value = Lonenum(Sud(cell.Row - 5, cell.Column - 1)): cell.Font.ColorIndex = 44: prohodresult = 1
For Col = 1 To 9
If Col cell.Column - 1 And Field.Cells(cell.Row - 5, Col).Value "" Then
If Hasnumber(Sud(cell.Row - 5, cell.Column - 1), Field.Cells(cell.Row - 5, Col).Value) = True Then Sud(cell.Row - 5, cell.Column - 1) = Sud(cell.Row - 5, cell.Column - 1) - 2 ^ (Field.Cells(cell.Row - 5, Col).Value - 1): prohodresult = 1
End If
Next Col
то же по рядам и зонам 3х3
в итоге, если в клетке остается лишь один возможный вариант цифры, пишем его.
соответственно, после каждого такого прохода по 9х9 что-то меняется. в итоге либо решение либо дошли до момента когда ничего не меняется
тогда применяем второй вариант. "если в первом ряду цифра 1 не может быть ни здесь ни здесь, а только здесь, то пишем ее"
перебираем для всех цифр.
(да, я знаю, что Goto это стыдно, но без него нужно было так извернуться что я бы не потянул умственно)
For Row = 1 To 9
For Count = 1 To 9
Exhod(Count, 1) = 0
Exhod(Count, 2) = 0
Next Count
For Col = 1 To 9
If Lonenum(Sud(Row, Col)) = 0 Then
For Count = 1 To 9
If Hasnumber(Sud(Row, Col), Count) = True Then Exhod(Count, 1) = Exhod(Count, 1) + 1: Exhod(Count, 2) = Col
Next Count
End If
Next Col
For Count = 1 To 9
If Exhod(Count, 1) = 1 Then Field.Cells(Row, Exhod(Count, 2)).Value = Count: Sud(Row, Exhod(Count, 2)) = 2 ^ (Count - 1): Field.Cells(Row, Exhod(Count, 2)).Font.ColorIndex = 42: GoTo prohod
Next Count
Next Row
это же все для всех рядов, для всех колонок и для всех зон
ну и там уже комбинация 1 и 2 вариантов - либо решили, либо неверные данные либо стопорнулись (но такого почти никогда не было - изначально проверка что минимум 22 клетки, не знаю почему именно это число, давно это было)
(В ролях:
Dim Sud(9, 9) As Integer
Dim Exhod(9, 2) As Integer
Dim Count, Row, Col, sektorX, sektorY As Integer
Dim Field As Range
....
Function Hasnumber(osnova As Integer, Numer As Variant) As Boolean
...
Function Lonenum(osnova2 As Integer) As Integer...)
хотя, когда понимаешь язык запросов и как построены реляционные базы, как работают индексы и т.д., уже не важно с чем именно работать.
Access никогда не пробовал. Если бы нужно было что-то легковесное бесплатное, втулил бы MS SQL Express
То есть решал правильно, только ответ получился неправильный? Ну так успокойся, тебе баллы начисляли правильно, только в результате небольших ошибок в вычислениях получилось 48. Не смертельно, живи дальше.
"Не смертельно, живи дальше."
Да я и не убиваюсь, самое главное что мне тогда как раз хватило на бюджет поступить