Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to .NET 9 #334

Merged
merged 22 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vsconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"components": [
"Microsoft.VisualStudio.Component.CoreEditor",
"Microsoft.VisualStudio.Workload.CoreEditor",
"Microsoft.NetCore.Component.Runtime.8.0",
"Microsoft.NetCore.Component.Runtime.9.0",
"Microsoft.NetCore.Component.SDK",
"Microsoft.VisualStudio.Component.Roslyn.Compiler",
"Microsoft.VisualStudio.Component.Roslyn.LanguageServices"
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<UseArtifactsOutput>true</UseArtifactsOutput>
<VersionPrefix>8.0.0</VersionPrefix>
<VersionPrefix>9.0.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
<PropertyGroup Condition=" '$(EnableReferenceTrimmer)' != 'false' and '$(GenerateDocumentationFile)' != 'true' ">
Expand Down
4 changes: 0 additions & 4 deletions benchmark.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ param(
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"

if ($null -eq ${env:MSBUILDTERMINALLOGGER}) {
${env:MSBUILDTERMINALLOGGER} = "auto"
}

$solutionPath = $PSScriptRoot
$sdkFile = Join-Path $solutionPath "global.json"

Expand Down
4 changes: 0 additions & 4 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ param(
[Parameter(Mandatory = $false)][switch] $SkipTests
)

if ($null -eq ${env:MSBUILDTERMINALLOGGER}) {
${env:MSBUILDTERMINALLOGGER} = "auto"
}

$Configuration = "Release"
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
Expand Down
4 changes: 0 additions & 4 deletions crank.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ param(
$ErrorActionPreference = "Stop"
$global:ProgressPreference = "SilentlyContinue"

if ($null -eq ${env:MSBUILDTERMINALLOGGER}) {
${env:MSBUILDTERMINALLOGGER} = "auto"
}

$additionalArgs = @()

if (![string]::IsNullOrEmpty($BranchOrCommitOrTag)) {
Expand Down
2 changes: 1 addition & 1 deletion crank.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
scenarios:
microbenchmarks:
application:
framework: net8.0
framework: net9.0
job: microbenchmarks

profiles:
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.404",
"version": "9.0.100",
"allowPrerelease": false,
"rollForward": "latestMajor"
}
Expand Down
2 changes: 1 addition & 1 deletion src/ProjectEuler/ProjectEuler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<PreserveCompilationContext>true</PreserveCompilationContext>
<PublishAot>true</PublishAot>
<RootNamespace>MartinCostello.ProjectEuler</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Puzzles\**\*.txt" />
Expand Down
4 changes: 0 additions & 4 deletions src/ProjectEuler/Puzzles/Puzzle014.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ public sealed class Puzzle014 : Puzzle
/// </summary>
private static readonly Dictionary<long, int> _cache = new(1_000_000);

#if NET9_0_OR_GREATER
private static readonly System.Threading.Lock _lock = new();
#else
private static readonly object _lock = new();
#endif

/// <inheritdoc />
public override string Question => "Which starting number, under one million, produces the longest chain?";
Expand Down
8 changes: 2 additions & 6 deletions src/ProjectEuler/Puzzles/Puzzle025.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,11 @@ internal static IEnumerable<BigInteger> Fibonacci()
/// <inheritdoc />
protected override int SolveCore(string[] args)
{
int index = 0;

foreach (BigInteger value in Fibonacci())
foreach ((int index, BigInteger value) in Fibonacci().Index())
{
index++;

if (value >= Limit)
{
Answer = index;
Answer = index + 1;
break;
}
}
Expand Down
13 changes: 6 additions & 7 deletions src/ProjectEuler/Puzzles/Puzzle042.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,16 @@ internal IList<string> ReadWords()
using var stream = ReadResource();
using var reader = new StreamReader(stream);

string rawWords = reader.ReadToEnd();
var text = reader.ReadToEnd().AsSpan();
var words = new List<string>();

string[] split = rawWords.Split(',');

var words = new List<string>(split.Length);

foreach (string word in split)
foreach (var word in text.Split(','))
{
words.Add(word.Trim('\"'));
words.Add(text[word].Trim('\"').ToString());
}

words.TrimExcess();

return words;
}

Expand Down
100 changes: 46 additions & 54 deletions src/ProjectEuler/Puzzles/Puzzle059.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Martin Costello, 2015. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System.Buffers;
using System.Text;

namespace MartinCostello.ProjectEuler.Puzzles;

/// <summary>
Expand All @@ -17,83 +14,78 @@ public sealed class Puzzle059 : Puzzle
/// <inheritdoc />
protected override int SolveCore(string[] args)
{
byte[] encrypted = LoadText();

byte[] alphabet = Enumerable.Range('a', 26)
.Select((p) => (byte)p)
.ToArray();

var passwords = new List<byte[]>((int)Math.Pow(alphabet.Length, 3));
const int AlphabetLength = 26;
const int KeyLength = 3;

for (int x = 0; x < alphabet.Length; x++)
ReadOnlySpan<char> passwords = string.Create(
AlphabetLength * AlphabetLength * AlphabetLength * KeyLength,
"abcdefghijklmnopqrstuvwxyz",
static (buffer, alphabet) =>
{
for (int y = 0; y < alphabet.Length; y++)
int i = 0;

for (int x = 0; x < alphabet.Length; x++)
{
for (int z = 0; z < alphabet.Length; z++)
for (int y = 0; y < alphabet.Length; y++)
{
passwords.Add([alphabet[x], alphabet[y], alphabet[z]]);
for (int z = 0; z < alphabet.Length; z++)
{
buffer[i] = alphabet[x];
buffer[i + 1] = alphabet[y];
buffer[i + 2] = alphabet[z];
i += KeyLength;
}
}
}
}
});

var encoding = Encoding.ASCII;
var encrypted = LoadText();
Span<char> decrypted = stackalloc char[encrypted.Length];

// Five most common English words
string[] commonWords =
[
" the ",
" of ",
" and ",
" a ",
" to ",
];

byte[][] words = commonWords.Select(encoding.GetBytes).ToArray();

byte[] key = new byte[encrypted.Length];
byte[] decrypted = new byte[encrypted.Length];

foreach (byte[] password in passwords)
for (int i = 0; i < passwords.Length; i += KeyLength)
{
for (int i = 0; i < key.Length;)
{
key[i++] = password[0];
key[i++] = password[1];
key[i++] = password[2];
}
var password = passwords.Slice(i, KeyLength);

for (int i = 0; i < decrypted.Length; i++)
for (int j = 0; j < decrypted.Length; j += KeyLength)
{
decrypted[i] = (byte)(encrypted[i] ^ key[i]);
decrypted[j] = (char)(encrypted[j] ^ password[0]);
decrypted[j + 1] = (char)(encrypted[j + 1] ^ password[1]);
decrypted[j + 2] = (char)(encrypted[j + 2] ^ password[2]);
}

ReadOnlySpan<byte> plaintext = decrypted;
ReadOnlySpan<char> span = decrypted;

if (plaintext.IndexOf(words[0]) > -1 &&
plaintext.IndexOf(words[1]) > -1 &&
plaintext.IndexOf(words[2]) > -1 &&
plaintext.IndexOf(words[3]) > -1 &&
plaintext.IndexOf(words[4]) > -1)
if (span.Contains("Euler", StringComparison.Ordinal))
{
Answer = decrypted.Select((p) => (int)p).Sum();
int sum = 0;

for (int j = 0; j < span.Length; j++)
{
sum += span[j];
}

Answer = sum;
break;
}
}

return 0;
}

private byte[] LoadText()
private ReadOnlySpan<char> LoadText()
{
using var stream = ReadResource();
using var reader = new StreamReader(stream);

string text = reader.ReadToEnd();
int length = 0;
ReadOnlySpan<char> text = reader.ReadToEnd();

string[] split = text.Split(',');

return split
.Select((p) => byte.Parse(p, CultureInfo.InvariantCulture))
.ToArray();
return string.Create(text.Length, text, (buffer, value) =>
{
foreach (var range in value.Split(','))
{
buffer[length++] = (char)byte.Parse(value[range], CultureInfo.InvariantCulture);
}
}).AsSpan()[..length];
}
}
24 changes: 24 additions & 0 deletions startvs.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@ECHO OFF
SETLOCAL

:: This command launches a Visual Studio solution with environment variables required to use a local version of the .NET SDK.

:: This tells .NET to use the same dotnet.exe that the build script uses.
SET DOTNET_ROOT=%~dp0.dotnetcli
SET DOTNET_ROOT(x86)=%~dp0.dotnetcli\x86

:: Put our local dotnet.exe on PATH first so Visual Studio knows which one to use.
SET PATH=%DOTNET_ROOT%;%PATH%

SET sln=%~dp0ProjectEuler.sln

IF NOT EXIST "%DOTNET_ROOT%\dotnet.exe" (
echo The .NET SDK has not yet been installed. Run `%~dp0build.ps1` to install it
exit /b 1
)

IF "%VSINSTALLDIR%" == "" (
start "" "%sln%"
) else (
"%VSINSTALLDIR%\Common7\IDE\devenv.com" "%sln%"
)
29 changes: 29 additions & 0 deletions startvscode.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@ECHO OFF
SETLOCAL

:: This command launches Visual Studio Code with environment variables required to use a local version of the .NET SDK.

:: This tells .NET to use the same dotnet.exe that the build script uses.
SET DOTNET_ROOT=%~dp0.dotnetcli
SET DOTNET_ROOT(x86)=%~dp0.dotnetcli\x86

:: Put our local dotnet.exe on PATH first so Visual Studio Code knows which one to use.
SET PATH=%DOTNET_ROOT%;%PATH%

:: Sets the Target Framework for Visual Studio Code.
SET TARGET=net9.0

SET FOLDER=%~1

IF NOT EXIST "%DOTNET_ROOT%\dotnet.exe" (
echo The .NET SDK has not yet been installed. Run `%~dp0build.ps1` to install it
exit /b 1
)

IF "%FOLDER%"=="" (
code .
) else (
code "%FOLDER%"
)

exit /b 1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<OutputType>Exe</OutputType>
<RootNamespace>MartinCostello.ProjectEuler.Benchmarks</RootNamespace>
<Summary>Benchmarks for ProjectEuler.</Summary>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ProjectEuler\ProjectEuler.csproj" />
Expand Down
2 changes: 1 addition & 1 deletion tests/ProjectEuler.Tests/ProjectEuler.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<NoWarn>$(NoWarn);CA1707;CA1812;CA1861;CA2007;SA1600</NoWarn>
<RootNamespace>MartinCostello.ProjectEuler</RootNamespace>
<Summary>Tests for ProjectEuler.</Summary>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
Expand Down