Category Archives: Uncategorized

Solve sudoku – WIP!

[CmdletBinding()]
Param()
Process{
    # Initial process. Clear all grids with hints.
    
    $Hash1 = 1 # Set Datahash 1 and 2 to different values.
    $Hash2 = 0
    While($Hash1 -notmatch $Hash2){
        $Hash1 = (1..9 | ForEach-Object{($Data | Where-Object{$_."ID"}).$_}).count
        Process-Sudoku
        $Hash2 = (1..9 | ForEach-Object{($Data | Where-Object{$_."ID"}).$_}).count
    }
}
Begin{
    #
    $MyPath = Split-Path $MyInvocation.MyCommand.path -Parent

    $Data = Import-Csv -Path "$MyPath\sudoku.txt" -Delimiter " "

    For($i = 1;$i -le 9;$i++){
        $currentRow = ($Data | Where-Object{$_."ID" -eq $i})
        For($n = 1;$n -le 9;$n++){
            $cell = [int32]($currentRow.$n)
            If($cell -eq 0){
                $currentRow.$n = (1..9)
            }
            Else{
                $currentRow.$n = [array]$cell
            }
        }
    }
    Function Process-Sudoku{
        
        # Process Horizontal
        For($i = 1;$i -le 9;$i++){
            If($Hash1 -le 162){} ## DEEBUUUGG
            $currentRow = $data[($i-1)]
            $exists = 1..9 | Foreach-Object{If(($currentRow.$_).count -eq 1){$currentRow.$_}}
            $NotSolved = 1..9 | Where-Object{($currentRow.$_).count -gt 1}
            $NotSolved | ForEach-Object{
                [Array]$NewArray = $currentRow.$_ | ForEach-Object{if($exists -match $_){}Else{$_}}
                $currentRow.$_ = $NewArray
            }
        }

        # Process Verical
        For($i = 1;$i -le 9;$i++){
            $CurrentLine = @{}
            For($n = 1;$n -le 9;$n++){
                $currentRow = $Data[($n-1)]
                $CurrentLine += @{$n = $currentRow.$i}
            }
            $Exists = 1..9 | Foreach-Object{If(($CurrentLine.$_).count -eq 1){$currentLine.$_}}
            $NotSolved = 1..9 | Where-Object{($CurrentLine.$_).count -gt 1}
            $NotSolved | ForEach-Object{
                For($n = 1;$n -le 9;$n++){
                    $currentRow = $Data[($_-1)]
                    [Array]$NewArray = $currentRow.$i | ForEach-Object{if($exists -match $_){}Else{$_}}
                    $currentRow.$i = $NewArray
                }
            }
        }
        # Process grid
        For($i = 1;$i -le 9;$i++){
            
            If($i -le 3){$Mod = 0}
            ElseIf($i -gt 6){$Mod = 6}
            Else{$Mod = 3}

            $CurrentGrid = @{}
            $c = 1
            For($n = 1;$n -le 3;$n++){
                $currentRow = $Data[($n+$mod-1)]
                For($x = 1;$x -le 3;$x++){
                    
                    $CurrentGrid += @{$c = $currentRow.$x}
                    $c++
                }
            }
            $exists = 1..9 | Foreach-Object{If(($CurrentGrid.$_).count -eq 1){$CurrentGrid.$_}}
            $NotSolved = 1..9 | Where-Object{($CurrentGrid.$_).count -gt 1}
            $NotSolved | ForEach-Object{
                If($_ -le 3){$row = 1}
                ElseIf($_ -ge 7){$row = 3}
                Else{$row = 2}
                $currentRow = $Data[($row+$mod-1)]
                [Array]$NewArray = $currentRow.$_ | ForEach-Object{if($exists -match $_){}Else{$_}}
                $currentRow.$_ = $NewArray
            }
        }
    } # End process function
}
End{
    $Data | Format-Table -AutoSize
}

Input

ID 1 2 3 4 5 6 7 8 9
1 9 0 0 0 0 0 1 2 0
2 0 0 2 3 0 0 0 0 0
3 4 0 0 0 0 5 9 6 0
4 0 8 0 2 0 0 6 0 0
5 0 0 0 0 5 0 0 0 0
6 0 0 1 0 0 9 0 3 0
7 0 7 6 9 0 0 0 0 1
8 0 0 0 0 0 1 7 0 0
9 0 9 8 0 0 0 0 0 4

Find primes, the proper way

I noticed that the earlier way to find primes is really fast for small numbers, but it is really really slow for number >5000

To shorten this, and provide a proper track of what primes are found as well as looping endlessly I’ve created this thing below.

Place it as prime.ps1 in a folder with read/write access.

The code below writes lines in a file called primes.log and keeps a progress of the last processed number (stored in progress.log).
This allows the script to resume the last location where it was terminated.
It also uses a better algorithm to determine if the given number is a prime or not, resulting in a steady 30 seconds to calculate 0-5000

Now the algorithm is not perfect (could check common divisible numbers first and some pattern matching) but it produces a steady stream of numbers in a fairly quick fashion.

[CmdletBinding()]
Param()
Process{
    
    If(!([int]$currentNumber = Get-Content $progressfile -ErrorAction Ignore)){[int]$currentNumber = $lastPrime+1}
    Write-Verbose "Starting at $currentNumber"

    "$(Get-Date -UFormat "%Y-%m-%d %r")| Starting at $currentNumber" | Out-File $logfile -Append

    While($Loop){
        
        Write-Verbose "Processing $currentNumber"
        $prime = Test-Prime $currentNumber
        
        If($prime){
            $currentNumber | Out-File $file -Append
            "$(Get-Date -UFormat "%Y-%m-%d %r")| Found prime, $currentNumber" | Out-File $logfile -Append
            Write-host "Success, prime found! $currentNumber" -ForegroundColor Green
        }
        
        $currentNumber++
        $currentNumber | Out-File $progressfile
    }
}
Begin{
    
    $MyPath = Split-Path $MyInvocation.MyCommand.path -Parent
    
    $Loop = $true
    $logfile = "$MyPath\log.log"
    $file = "$MyPath\primes.log"
    $progressfile = "$MyPath\progress.log"
    Try{
        $primes = Get-Content $file -ErrorAction Ignore
        [int]$lastPrime = $primes[-1]
        Write-Verbose "File found, last prime is $lastprime"
    }
    Catch{
        Write-Verbose "File not found. Creating file and starting from 3"
        $lastPrime = 3
        New-Item -Path $file -ItemType file -Force
        "2","3" | ForEach-Object{$_ | Out-File $file -Append}
    }

    Function Test-Prime{
        Param($number)
        If($number -match "0$|2$|4$|5$|6$|8$"){
            return $false
        }
        [int]$DivNumber = $number/2
        #$numbers = 2..$DivNumber
        $i = 2
        While($i -le $DivNumber){
            If($number%$i -eq 0){
                return $false
            }
            $i++
        }
        return $true
    }
}

Alcohol calculator

Calculate the amount of pure alchohol in litre you consume per year. All forms needs to be filled in.

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$Form = New-Object 'System.Windows.Forms.Form'
  
$Calculate = {
    
[double]$Result = 0
[double]$beer = $BeerTextBox.Text
[double]$wwine = $WhiteWineTextBox.Text
[double]$rwine = $RedWineTextBox.Text
[double]$spirit = $SpiritTextBox.Text
$result = ($beer*0.5*0.05)+($wwine*0.7*0.08)+($rwine*0.7*0.13)+($spirit*0.7*0.4)
$ResultBox.Text = $Result
}

$Form.Size = "300,300"

$BeerLabel = New-Object 'System.Windows.Forms.Label'
$BeerLabel.Text = "Beer"
$BeerLabel.Location = "10,10"
$BeerLabel.Size = "70,15"
$Form.Controls.add($BeerLabel)

$BeerTextBox = New-Object 'System.Windows.Forms.TextBox'
$BeerTextBox.Location = "80,10"
$BeerTextBox.Text = "~ Antal 50cl 5%"
$Form.Controls.add($BeerTextBox)

$WhiteWineLabel = New-Object 'System.Windows.Forms.Label'
$WhiteWineLabel.Text = "White Wine"
$WhiteWineLabel.Location = "10,25"
$WhiteWineLabel.Size = "70,15"
$Form.Controls.add($WhiteWineLabel)

$WhiteWineTextBox = New-Object 'System.Windows.Forms.TextBox'
$WhiteWineTextBox.Location = "80,25"
$WhiteWineTextBox.Text = "~ Antal 70cl 8%"
$Form.Controls.add($WhiteWineTextBox)

$RedWineLabel = New-Object 'System.Windows.Forms.Label'
$RedWineLabel.Text = "Red Wine"
$RedWineLabel.Location = "10,40"
$RedWineLabel.Size = "70,15"
$Form.Controls.add($RedWineLabel)

$RedWineTextBox = New-Object 'System.Windows.Forms.TextBox'
$RedWineTextBox.Location = "80,40"
$RedWineTextBox.Text = "~ Antal 70cl 13%"
$Form.Controls.add($RedWineTextBox)

$SpiritLabel = New-Object 'System.Windows.Forms.Label'
$SpiritLabel.Text = "Spirit"
$SpiritLabel.Location = "10,55"
$SpiritLabel.Size = "70,15"
$Form.Controls.add($SpiritLabel)

$SpiritTextBox = New-Object 'System.Windows.Forms.TextBox'
$SpiritTextBox.Location = "80,55"
$SpiritTextBox.Text = "~ Antal 70cl 40%"
$Form.Controls.add($SpiritTextBox)

$CalcButton = New-Object 'System.Windows.Forms.Button'
$CalcButton.Location = "10,90"
$CalcButton.Size = "100,40"
$CalcButton.Text = "Calculate"
$CalcButton.add_Click($calculate)
$Form.Controls.add($CalcButton)

$ResultBox = New-Object 'System.Windows.Forms.Label'
$ResultBox.Location = "10,155"
$ResultBox.Size = "100,25"
$ResultBox.Text = "inget ännu"
$Form.Controls.add($ResultBox)

$AverageLabel = New-Object 'System.Windows.Forms.Label'
$AverageLabel.Location = "10,130"
$AverageLabel.Size = "150,25"
$AverageLabel.Text = "Medel i sverige är 10,3"
$Form.Controls.add($AverageLabel)

$Form.showdialog()

Custom progress bar

Not that anyone wants or needs it, but here is a custom progress bar!

31

54

It has two modes. Loop and step. And is called like below.

PS> 0..99 | ForEach-Object{"Processing, current step $_";Start-Sleep -Milliseconds 200;.\epicship.ps1 -step $_};"Installation complete!"
 .\epicship.ps1 -loop

The Loop has more functions, such as a sun shining and getting obscured by the ship (notice the reflections dissapearing as the sunrays are blocked by the ship).

Loop
Capture

Param(
    [int]$step,
    [Switch]$Loop,
    [string]$FlagMsg,
    [int]$speed = 500,
    $condition = $False
)

$ErrorActionPreference = "SilentlyContinue"

if($step -gt 100){Write-Error "Step cannot exceed 100";Break}
[int]$step = $step/100*77
if($step -le 0){$step++}
#[console]::CursorVisible = $False

Function Animatrix{
    Param(
        [switch]$Loop,
        [int]$step
    )

    if($Loop){$action = "Loop"}
    Elseif($step){$action = "Step"}

    $ship = "                                                                                                                    "
    if(!($FlagMsg)) { $FlagMsg = "LOADING.-" } else { 

    $FlagMsg = "$FlagMsg-." 

    if($flagmsg.length -gt 22) { 
      write-error "Flag text is too long .. max 20 characters!!"
      Break
    }

    }

    # Add padding to left
    while($FlagMsg.length -lt 22) {
      $FlagMsg = " $FlagMsg"
    }

    # Add padding to right
    while($FlagMsg.length -lt 116) {
      $FlagMsg += ' '
    }  
    $ship += $FlagMsg
$ship += @'

                 |                                                                                                  
         Ya...___|__..ab.     .   .                                                                                 
          Y88b##\88b##\88b   (     )                                                                                
           Y88b##:88b##:88b   `.oo'                                                                                 
           :888##|888##|888  ( (`-'                                                                                 
  .-.      d88P##;88P##;88P   `.`.                                                                                  
 //._)    d8P-"""|"""'-Y8P      `.`.                                                                                
(o(`    .-.  .-. |.-.  .-.  .-.  )oo)                                                                               
 \o`---(-O-)(-O-)(-O)(-O-)(-O-)-'//                                                                                 
~~`.~~~~`-'~~`-'~~`-'~~`-'~~`-'~~.'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   `----------------------------'                                                                                   
'@ 

    $arrship = $ship.Split("`n")
    $saveY = [console]::CursorTop
    $saveX = [console]::CursorLeft
    Switch($action){
        "Loop"{

            0..109 | ForEach-Object{
                $i = 0
                $arrship | ForEach-Object{
                    If($i -eq $arrship.count-2){
                        $arrship[$i] = "~" + $arrship[$i].Substring(0,$arrship[$i].Length-1)
                    }
                    else{$arrship[$i] = " " + $arrship[$i].Substring(0,$arrship[$i].Length-1)}
                    $i++
                }
                $n = 0
                $chance = 0
                $sunpos = 60,75
                $sunMultiplier = 0.28
                $arrship | ForEach-Object{
                    $nChar = 0
                    If($n -eq $arrship.Count-5){
                    [char[]]$arrship[$n] | ForEach-Object{
                        If(($nChar -ge $sunpos[0]+5) -and ($nChar -le $sunpos[1]-5)){
                            If($_ -eq " "){Write-Host $_ -BackgroundColor Yellow -NoNewline;$chance += $sunMultiplier}
                            Else{Write-Host $_ -ForegroundColor Yellow -NoNewline}
                        }
                        Elseif($nChar -lt 116){Write-Host $_ -ForegroundColor DarkGray -NoNewline}
                        Else{Write-Host $_ -ForegroundColor DarkGray}
                        $nChar++
                        }
                    }
                    ElseIf($n -eq $arrship.Count-4){
                    [char[]]$arrship[$n] | ForEach-Object{
                        If(($nChar -ge $sunpos[0]+2) -and ($nChar -le $sunpos[1]-2)){
                            If($_ -eq " "){Write-Host $_ -BackgroundColor Yellow -NoNewline;$chance += $sunMultiplier}
                            Else{Write-Host $_ -ForegroundColor Yellow -NoNewline}
                        }
                        Elseif($nChar -lt 116){Write-Host $_ -ForegroundColor DarkGray -NoNewline}
                        Else{Write-Host $_ -ForegroundColor DarkGray}
                        $nChar++
                        }
                    }
                    ElseIf($n -eq $arrship.Count-3){
                    [char[]]$arrship[$n] | ForEach-Object{
                        If(($nChar -ge $sunpos[0]) -and ($nChar -le $sunpos[1]) -and ($_ -eq " ")){Write-Host $_ -BackgroundColor Yellow -NoNewline;$chance += $sunMultiplier}
                        Elseif($nChar -lt 116){Write-Host $_ -ForegroundColor DarkGray -NoNewline}
                        Else{Write-Host $_ -ForegroundColor DarkGray}
                        $nChar++
                        }
                    }
                    ElseIf($n -eq $arrship.count-2){Write-Host $arrship[$n] -ForegroundColor Blue}
                    Elseif($n -eq $arrship.count-1){Write-Host $arrship[$n] -ForegroundColor Cyan}
                    Else{Write-host $arrship[$n] -ForegroundColor DarkGray}
                    $n++
                }

                wavegen -modulus 3 -SunXY $sunpos -chance $chance
                wavegen -modulus 10 -SunXY $sunpos -chance $chance
                wavegen -modulus 30 -SunXY $sunpos -chance $chance
                wavegen -modulus 200 -SunXY $sunpos -chance $chance
                $refchance = $chance*10
                "chance of reflection is: $refchance%"

                Start-Sleep -Milliseconds $speed

                [console]::setcursorposition($saveX,$saveY)
            }
        }
        "Step"{
            Clear-Host
            $i = 0
            $arrship | ForEach-Object{
                If($i -eq $arrship.count-2){$arrship[$i] = "~"*$step + $arrship[$i].Substring(0,$arrship[$i].Length-1*$step)}
                else{$arrship[$i] = " "*$step + $arrship[$i].Substring(0,$arrship[$i].Length-1*$step)}
                    $i++
            }
            $n = 0
            $arrship | ForEach-Object{
                If($n -eq $arrship.count-2){Write-Host $arrship[$n] -ForegroundColor Blue}
                elseif($n -eq $arrship.count-1){Write-Host $arrship[$n] -ForegroundColor Cyan}
                Else{Write-host $arrship[$n] -ForegroundColor Yellow}
                $n++
            }
            $chance = 7
            $sun = 30,45

            wavegen -modulus 3 -SunXY $sun -chance $chance
            wavegen -modulus 10 -SunXY $sun -chance $chance
            wavegen -modulus 30 -SunXY $sun -chance $chance
            wavegen -modulus 200 -SunXY $sun -chance $chance
        }
    }
}

function wavegen{
    Param(
        [int]$modulus,
        [array]$SunXY,
        [int]$chance
    )
    $test = 0
    0..115 | ForEach-Object{
        $test++
        $rand = get-random -Maximum 1000  
        $rand%$modulus
    } | ForEach-Object{

            $i = Get-random -maximum 5  
            If(($test -ge $SunXY[0]) -and ($test -le $SunXY[1]) -and ((Get-Random -Maximum 10) -lt $chance)){
                $color = "Yellow"
            }Else{
                If($i%2 -eq 0){$color = "DarkBlue"} 
                else{$color = "blue"}  
            }
            if($_ -eq 1){

                write-host -foregroundcolor $color "~" -NoNewline        
            }
            elseif($_ -eq 2){
                Write-Host -ForegroundColor $color "-" -NoNewline
            }
            elseif($_ -eq 3){
                Write-Host -ForegroundColor $color "_" -NoNewline
            }
            else{Write-host " " -NoNewline}  
    }
    Write-host " "
}

If($Loop){
    Animatrix
    While($condition -eq $False){
        Animatrix -Loop
    }
}
Elseif($step){
    Animatrix -step $step
    [console]::setcursorposition($saveX,$saveY)
}
Else{
    Write-Warning "You're doing it wrong!"
}

FileDialogs

Function SaveFileDialog{
    Param(
        [Parameter(Mandatory=$True)]
        $Filetype
    )
    [Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
    $SaveFileDialog.Filter = "$Filetype files (*.$Filetype)|*.$Filetype|All files (*.*)|*.*"
    $status = $SaveFileDialog.ShowDialog()

    If($status -eq "Cancel"){$Return = $status}
    Else{$Return = $SaveFileDialog.FileName}

    $SaveFileDialog.Dispose()
    Return $Return
}
Function SelectFileDialog{
    Param(
        [Parameter(Mandatory=$True)]
        $Filetype
    )
    [Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog

    $OpenFileDialog.Filter = "$Filetype files (*.$Filetype)|*.$Filetype|All files (*.*)|*.*"

    $status = $OpenFileDialog.ShowDialog()

    If($status -eq "Cancel"){$Return = $status}
    Else{$Return = $OpenFileDialog.FileName}

    $OpenFileDialog.Dispose()
    Return $Return
}
Function SelectFolderDialog{
    [Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

    $SelectFileDialog = New-Object System.Windows.Forms.FolderBrowserDialog
    $status = $SelectFileDialog.ShowDialog()

    If($status -eq "Cancel"){$Return = $status}
    Else{$Return = $SelectFileDialog.FileName}

    $SelectFileDialog.Dispose()
    Return $Return
}

Beta testing and error handling

Here is a simple snippet that you can run to output all exceptions in a script.

$ErrorActionPreference = "SilentlyContinue"

IWillProduceAnError

#----------------------------------------------------------------
# Debug function, dumps all errors in $Error variable to file
#----------------------------------------------------------------

Function Dump-Errors(){
    Param(
        [Parameter(Position=0, Mandatory = $True)]
        [String]$Logfile
    )
    $Error | Add-Content $Logfile
    $Error.Clear()
}

Dump-Errors -logfile "c:\temp\script.log"

If you look at the code, the cmdlet “IWillProduceAnError” is most likely not recognized and will produce an exception.
However, you have the $ErrorActionPreference set to SilentlyContinue so nothing will show for the user.

This is where the dump-errors function will help you catch errors you would otherwise never see.

Place the function in your code and make sure the last line to run is the function.
It will output all exceptions in the $Error variable to a file. You can then later collect the file from the users you know are beta testing and use the Try/Catch statements to correct your code. Combine this with the Powershell auto updater in silent mode and the user will never know you updated the code.