<commit_before>﻿// Copyright (c) <NAME>. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using SudokuSolverLib.Helpers;
using SudokuSolverLib.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace SudokuSolverLib
{
    public class SudokuPuzzle
    {
        private SudokuInternalNode[,] nodes;
        private bool hasSolution;
        private readonly int boxWidth;
        private readonly int boxHeight;
        private readonly int possibleNodeValueCount;
        private readonly ulong winMask;

        public int BoxWidth { get { return boxWidth; } }
        public int BoxHeight { get { return boxHeight; } }
        public bool HasSolution { get { return hasSolution; } }

        #region Factory methods and ctors
        public static SudokuPuzzle FromString(string puzzle, int boxWidth, int boxHeight)
        {
            if (string.IsNullOrEmpty(puzzle))
                throw new ArgumentException("Puzzle cannot be empty", "puzzle");

            if (boxWidth <= 0 || boxHeight <= 0)
                throw new ArgumentException("Cannot have a negative or zero puzzle size");

            if (boxWidth > 5 || boxHeight > 5)
                throw new ArgumentException("Cannot have a puzzle box size larger than 16x16");

            return new SudokuPuzzle(puzzle, boxWidth, boxHeight);
        }

        public static SudokuPuzzle Create(int boxWidth, int boxHeight, int hintsCount)
        {
            if (boxWidth <= 0 || boxHeight <= 0)
                throw new ArgumentException("Invalid box size");

            if (boxWidth > 5 || boxHeight > 5)
                throw new ArgumentException("Cannot have a puzzle box size larger than 16x16");

            if (hintsCount < 0 || hintsCount > (boxHeight * boxHeight * boxWidth * boxWidth))
                throw new ArgumentException("Invalid hints count");

            Random randomizer = new Random((int)DateTime.Now.Ticks);
            ValuesProvider randomizedValuesProvider = new ValuesProvider(boxWidth * boxHeight, randomizer);

            // Create a new grid by solving an empty grid using a randomized order of picking values
            SudokuPuzzle grid = new SudokuPuzzle(boxWidth, boxHeight);
            grid.SolveGrid(randomizedValuesProvider);

            // Create a new grid by taking hintsCount hints from the solved grid.
            int[] hintsLocation = ArrayHelpers.RandomizedRange(boxHeight * boxWidth * boxHeight * boxWidth, randomizer);

            SudokuPuzzle resultGrid = new SudokuPuzzle(boxWidth, boxHeight);

            var x = grid.GetNodes().ToArray();
            for (int i = 0; i < hintsCount; i++)
            {
                resultGrid.SetValue(x[hintsLocation[i]].Line, x[hintsLocation[i]].Column, x[hintsLocation[i]].Value, true);
            }

            return resultGrid;
        }

        private SudokuPuzzle(int boxWidth, int boxHeight)
        {
            this.boxHeight = boxHeight;
            this.boxWidth = boxWidth;
            possibleNodeValueCount = boxHeight * boxWidth;
            winMask = ulong.MaxValue << possibleNodeValueCount;

            // Create the nodes
            nodes = new SudokuInternalNode[possibleNodeValueCount, possibleNodeValueCount];
            for (int i = 0; i < possibleNodeValueCount; i++)
            {
                for (int j = 0; j < possibleNodeValueCount; j++)
                {
                    nodes[i, j] = new SudokuInternalNode(i, j, possibleNodeValueCount);
                }
            }
        }

        private SudokuPuzzle(string puzzle, int width, int height)
            : this(width, height)
        {
            CreateGridNodesFromPuzzle(puzzle, width, height);

            // Update the neighbours based on the information in the puzzle.<commit_msg>Add Manual Seed Value<commit_after>﻿// Copyright (c) <NAME>. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using SudokuSolverLib.Helpers;
using SudokuSolverLib.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace SudokuSolverLib
{
    public class SudokuPuzzle
    {
        private SudokuInternalNode[,] nodes;
        private bool hasSolution;
        private readonly int boxWidth;
        private readonly int boxHeight;
        private readonly int possibleNodeValueCount;
        private readonly ulong winMask;

        public int BoxWidth { get { return boxWidth; } }
        public int BoxHeight { get { return boxHeight; } }
        public bool HasSolution { get { return hasSolution; } }

        #region Factory methods and ctors
        public static SudokuPuzzle FromString(string puzzle, int boxWidth, int boxHeight)
        {
            if (string.IsNullOrEmpty(puzzle))
                throw new ArgumentException("Puzzle cannot be empty", "puzzle");

            if (boxWidth <= 0 || boxHeight <= 0)
                throw new ArgumentException("Cannot have a negative or zero puzzle size");

            if (boxWidth > 5 || boxHeight > 5)
                throw new ArgumentException("Cannot have a puzzle box size larger than 16x16");

            return new SudokuPuzzle(puzzle, boxWidth, boxHeight);
        }

        public static SudokuPuzzle Create(int boxWidth, int boxHeight, int hintsCount)
        {
            if (boxWidth <= 0 || boxHeight <= 0)
                throw new ArgumentException("Invalid box size");

            if (boxWidth > 5 || boxHeight > 5)
                throw new ArgumentException("Cannot have a puzzle box size larger than 16x16");

            if (hintsCount < 0 || hintsCount > (boxHeight * boxHeight * boxWidth * boxWidth))
                throw new ArgumentException("Invalid hints count");

            Random randomizer = new Random((int)DateTime.Now.Ticks);
            ValuesProvider randomizedValuesProvider = new ValuesProvider(boxWidth * boxHeight, randomizer);

            // Create a new grid by solving an empty grid using a randomized order of picking values
            SudokuPuzzle grid = new SudokuPuzzle(boxWidth, boxHeight);
            grid.SolveGrid(randomizedValuesProvider);

            // Create a new grid by taking hintsCount hints from the solved grid.
            int[] hintsLocation = ArrayHelpers.RandomizedRange(boxHeight * boxWidth * boxHeight * boxWidth, randomizer);

            SudokuPuzzle resultGrid = new SudokuPuzzle(boxWidth, boxHeight);

            var x = grid.GetNodes().ToArray();
            for (int i = 0; i < hintsCount; i++)
            {
                resultGrid.SetValue(x[hintsLocation[i]].Line, x[hintsLocation[i]].Column, x[hintsLocation[i]].Value, true);
            }

            return resultGrid;
        }
		public static SudokuPuzzle Create(int boxWidth, int boxHeight, int hintsCount, int Seed)
		{
			if (boxWidth <= 0 || boxHeight <= 0)
				throw new ArgumentException("Invalid box size");

			if (boxWidth > 5 || boxHeight > 5)
				throw new ArgumentException("Cannot have a puzzle box size larger than 16x16");

			if (hintsCount < 0 || hintsCount > (boxHeight * boxHeight * boxWidth * boxWidth))
				throw new ArgumentException("Invalid hints count");

			Random randomizer = new Random(Seed);
			ValuesProvider randomizedValuesProvider = new ValuesProvider(boxWidth * boxHeight, randomizer);

			// Create a new grid by solving an empty grid using a randomized order of picking values
			SudokuPuzzle grid = new SudokuPuzzle(boxWidth, boxHeight);
			grid.SolveGrid(randomizedValuesProvider);

			// Create a new grid by taking hintsCount hints from the solved grid.
			int[] hintsLocation = ArrayHelpers.RandomizedRange(boxHeight * boxWidth * boxHeight * boxWidth, randomizer);

			SudokuPuzzle resultGrid = new SudokuPuzzle(boxWidth, boxHeight);

			var x = grid.GetNodes().ToArray();
			for (int i = 0; i < hintsCount; i++)
			{
				resultGrid.SetValue(x[hintsLocation[i]].Line, x[hintsLocation[i]].Column, x[hintsLocation[i]].Value, true);
			}

			return resultGrid;
		}
		private SudokuPuzzle(int boxWidth, int boxHeight)
        {
            this.boxHeight = boxHeight;
            this.boxWidth = boxWidth;
            possibleNodeValueCount = boxHeight * boxWidth;
            winMask = ulong.MaxValue << possibleNodeValueCount;

            // Create the nodes
            nodes = new SudokuInternalNode[possibleNodeValueCount, possibleNodeValueCount];
            for (int i = 0; i < possibleNodeValueCount; i++)
            {
                for (int j = 0; j < possibleNodeValueCount; j++)
                {
                    nodes[i, j] = new SudokuInternalNode(i, j, possibleNodeValueCount);
                }
            }
        }

        private SudokuPuzzle(string puzzle, int width, int height)
            : this(width, height)
        {
            CreateGridNodesFromPuzzle(puzzle, width, height);

            // Update the neighbours based on the information in the puzzle.
{'fraction_non_alphanumeric': 0.08191349934469201, 'fraction_numerical': 0.005460899956312801, 'mean_word_length': 2.4633131618759454, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6098638', 'n_tokens_mistral': 2531, 'n_tokens_neox': 2292, 'n_words': 780}