Übersetzung Python --> C# richtig?

  • C#

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von VB.neter0101.

    Übersetzung Python --> C# richtig?

    Hallo,

    ich übe mich gerade daran folgenden Python Code in C# zu übersetzen:

    Quellcode

    1. def solve():
    2. for y in range(9) :
    3. for x in range(9) :
    4. if grid[y][x] == 0 :
    5. for n in range(1,10) :
    6. if CheckPlace(y,x,n) :
    7. grid[y][x] = n
    8. solve()
    9. grid[y][x] = 0
    10. return
    11. print(grid)


    Jetzt habe ich versucht das in C# zu übersetzen:

    C#-Quellcode

    1. private static void solve()
    2. {
    3. for (int y = 0; y < 9; y++)
    4. {
    5. for (int x = 0; x < 9; x++)
    6. {
    7. if (grid[y][x] == 0)
    8. {
    9. for (int n = 1; n < 10; n++) // gefix nach Vorschlag von petaod
    10. {
    11. if (CheckPlace(y, x, n))
    12. {
    13. grid[y][x] = n;
    14. solve();
    15. grid[y][x] = 0;
    16. }
    17. }
    18. return;
    19. }
    20. }
    21. }
    22. }


    Den Print Befehl aus dem Python Code habe ich einmal weggelassen. Meine IDE zeigt mir an der Stelle des return Statements im C# Code an, dass diese Stelle niemals erreicht wird. Außerdem entstehen für n auch Werte wie 11, 12, 13, wobei ich mir die Frage stelle warum das so ist, da n ja immer wieder neu in der Schleife initialisiert wird, wenn diese aufgerufen wird. In Python scheint der Code aber so zu funktionieren...

    *Topic verschoben*

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Das kann doch nicht sein... Den drucke ich mir gleich aus und hänge den an meine Zimmer Wand. So ein dummer Fehler...

    Selbst wenn ich dass jetzt so anpasse funktioniert der C# Code noch nicht richtig, anscheinend verarbeitet Python den Nachfolgenden Teil also solve(); grid[y][x] = 0; anders als C# das tut...

    So innerhalb des Backtrackings war noch ein Fehler, außerdem darf die Methode (vermutlich) nicht void sein (warum auch immer Python das dennoch schafft...). Unter Berücksichtigung der Änderungen lautet der neue Code dann:

    C#-Quellcode

    1. private static bool solve()
    2. {
    3. for (int y = 0; y < 9; y++)
    4. {
    5. for (int x = 0; x < 9; x++)
    6. {
    7. if (grid[y][x] == 0)
    8. {
    9. for (int n = 1; n < 10; n++)
    10. {
    11. if (CheckPlace(y, x, n))
    12. {
    13. grid[y][x] = n;
    14. if (solve())
    15. {
    16. return true;
    17. }
    18. else
    19. {
    20. grid[y][x] = 0;
    21. }
    22. }
    23. }
    24. return false;
    25. }
    26. }
    27. }
    28. return true;
    29. }


    Ich bin jetzt in Python nicht ganz so erfahren, daher wäre meine nächste Frage, warum das in Python so einfach geht, wohingegen das in C# (gefühlt) komplexer ausfällt (In Python sehe ich z.B. nicht, dass vor dem Aufruf von solve() noch eine IF Abfrage kommt, außerdem fehlen die returns, die in C# verwendet werden mussten...)?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VB.neter0101“ ()

    Das ist deswegen komplexer, weil du in C# komplexeren Code geschrieben hast - weder das if (solve()) noch die zusätzlichen returns existieren so im Python-Code, weder explizit noch implizit. Die Methode in Python gibt auch nichts zurück - das ​return wird nur dafür verwendet, die Methode zu beenden. In C# wäre das auch ne ​void-Methode.
    @nafets darf ich fragen, wenn das so ist, warum funktioniert dann der eingangs von mir gelieferte übersetzte C# Code nicht? Weil tendenziell würde ich sagen ist das eine 1-zu-1 Übersetzung, daher wundre ich mich, dass das C# Beispiel so nicht funktioniert, wohingegen der Python Code läuft.

    Jeder andere hier, der sich mit Python auskennt, ist natürlich gerne eingeladen, hier ebenfalls auszuhelfen :) Meine Frage ist vordergründig, wie der oben stehende Python Code in C# umgesetzt werden würde. :)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VB.neter0101“ ()

    Die anderen Methoden, die du verwendest, verhalten sich dann halt anders als beim Äquivalent in Python. Die erste Variante war, bis auf die ursprünglich falsche for-Schleife, eine absolut korrekte 1:1-Übersetzung vom Python-Code in C#.
    Ich sehe das auch so, dass meine erste Version eine 1:1 Übersetzung von Python in C# war. Ich habe mir die Rekursion nachmal angesehen, das hatte ich nicht beachtet, ich muss sobald ich eine Lösung gefunden habe, diese auch ausgeben (das fehlte im C# Code bzw. war nicht in der Methode definiert, sondern wurde ausgeführt nachdem die Methode ausgeführt wurde, infolgedessen ist mir dann also immer das Ursprüngliche Grid angezeigt worden (ohne die Lösung)), dann funktioniert es!

    Danke für die Hilfe hier!

    Wer sich für die Übersetzung interessiert:

    C#-Quellcode

    1. public static void solve()
    2. {
    3. for (int y = 0; y < 9; y++)
    4. {
    5. for (int x = 0; x < 9; x++)
    6. {
    7. if (grid[y][x] == 0)
    8. {
    9. for (int n = 1; n < 10; n++)
    10. {
    11. if (CheckPlace(y, x, n))
    12. {
    13. grid[y][x] = n;
    14. solve();
    15. grid[y][x] = 0;
    16. }
    17. }
    18. return;
    19. }
    20. }
    21. }
    22. // Hilfsmethode, die das Grid auf der Konsole ausgibt
    23. printGrid(grid);
    24. }


    Bei printGrid(grid) handelt es sich dann um eine Hilfsmethode, die das 2D Array ausgibt. Verzichtet man auf diese Methode, dann wird zwar eine Lösung gefunden, aber diese wird nicht ausgegeben. Das Problem ist, dass sobald die Lösung gefunden wurde, die übrigen Rekursionen noch durchlaufen werden, die verändern das Eingabe 2D Array (Grid) in diesem Fall soweit ab, als dass das ursprüngliche 2D Grid ohne die Lösung wieder erscheint. Führe ich also solve(); aus ohne ein entsprechendes printGrid(grid) innerhalb der Methode solve() aufzurufen, dann wird die Lösung gefunden aber nicht ausgegeben. Durch die verbleibenden Rekursionen ändert sich das Array wieder ab (das Grid). Mein Fehler war, solve() zu implementieren und dann nachdem solve() ausgeführt wurde die Methode printGrid(grid) aufzurufen, sodass ich dann immer das Eingangs definierte Grid ausgegeben habe, statt der Lösung.

    Wer sich für das Projekt interessiert, es handelt sich um einen Sudoku Solver via Backtracking, nach Conceptual Programming with Python. In C# ist dies folgende Implementierung:

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace SudokuSolverBacktrackingAlgo
    7. {
    8. class Program
    9. {
    10. static int[][] sudokuGrid = new int[9][];
    11. static void Main(string[] args)
    12. {
    13. sudokuGrid[0] = new int[] { 5, 3, 0, 0, 7, 0, 0, 0, 0 };
    14. sudokuGrid[1] = new int[] { 6, 0, 0, 1, 9, 5, 0, 0, 0 };
    15. sudokuGrid[2] = new int[] { 0, 9, 8, 0, 0, 0, 0, 6, 0 };
    16. sudokuGrid[3] = new int[] { 8, 0, 0, 0, 6, 0, 0, 0, 3 };
    17. sudokuGrid[4] = new int[] { 4, 0, 0, 8, 0, 3, 0, 0, 1 };
    18. sudokuGrid[5] = new int[] { 7, 0, 0, 0, 2, 0, 0, 0, 6 };
    19. sudokuGrid[6] = new int[] { 0, 6, 0, 0, 0, 0, 2, 8, 0 };
    20. sudokuGrid[7] = new int[] { 0, 0, 0, 4, 1, 9, 0, 0, 5 };
    21. sudokuGrid[8] = new int[] { 0, 0, 0, 0, 8, 0, 0, 7, 9 };
    22. Console.WriteLine("Input Sudoku:");
    23. PrintSudoku();
    24. Console.WriteLine("\nSudoku Solution:");
    25. SudokuBacktrackingAlgorithm();
    26. Console.ReadKey();
    27. }
    28. public static void PrintSudoku()
    29. {
    30. for (int row = 0; row < sudokuGrid.Length; row++)
    31. {
    32. for (int column = 0; column < sudokuGrid[row].Length; column++)
    33. {
    34. Console.Write(sudokuGrid[row][column] + " ");
    35. }
    36. Console.WriteLine();
    37. }
    38. }
    39. public static void SudokuBacktrackingAlgorithm()
    40. {
    41. for (int row = 0; row < 9; row++)
    42. {
    43. for (int column = 0; column < 9; column++)
    44. {
    45. if (sudokuGrid[row][column] == 0)
    46. {
    47. for (int valueCandidates = 1; valueCandidates < 10; valueCandidates++)
    48. {
    49. if (CheckPlace(row, column, valueCandidates))
    50. {
    51. sudokuGrid[row][column] = valueCandidates;
    52. SudokuBacktrackingAlgorithm();
    53. sudokuGrid[row][column] = 0;
    54. }
    55. }
    56. return;
    57. }
    58. }
    59. }
    60. PrintSudoku();
    61. }
    62. private static bool CheckPlace(int _row, int _column, int _valueToCheck)
    63. {
    64. for(int i = 0; i < 9; i++)
    65. {
    66. if(sudokuGrid[_row][i] == _valueToCheck)
    67. {
    68. return false;
    69. }
    70. }
    71. for(int i = 0; i < 9; i++)
    72. {
    73. if (sudokuGrid[i][_column] == _valueToCheck)
    74. {
    75. return false;
    76. }
    77. }
    78. int x0 = (_column / 3) * 3;
    79. int y0 = (_row / 3) * 3;
    80. // Checks the 3x3 fields for possible candidates
    81. for(int i = 0; i < 3; i++)
    82. {
    83. for(int j = 0; j < 3; j++)
    84. {
    85. if(sudokuGrid[y0+i][x0+j] == _valueToCheck)
    86. {
    87. return false;
    88. }
    89. }
    90. }
    91. return true;
    92. }
    93. }
    94. }

    Dieser Beitrag wurde bereits 12 mal editiert, zuletzt von „VB.neter0101“ ()