Check a .udc section multiplier against the list the file names

MultWindowType names the list N1MM validates a received section against,
and every exchange that was not all digits counted as a multiplier here.
Four of N1MM's lists are held now -- the ARRL sections, the US states,
the Canadian provinces and the 165 OK/OM districts, which came out of
N1MM's own exe -- and a file naming one of them counts only the values
on it. A file naming any of the hundred-odd others keeps the old rule.

The 2023 OK/OM DX log now scores contact for contact as N1MM did. Two
contacts in the 2026 log still differ: the district code is stored with
a trailing space, which N1MM matches against its list untrimmed, so it
counts no multiplier where this counts one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
This commit is contained in:
2026-08-31 13:30:27 +00:00
co-authored by Claude Opus 5
parent 921033cd93
commit 1d3167cd04
5 changed files with 100 additions and 22 deletions
+19 -8
View File
@@ -1,3 +1,4 @@
using Nonemm.Contests.Multipliers;
using Nonemm.Core;
namespace Nonemm.Contests.Udc;
@@ -17,6 +18,7 @@ public sealed class UdcMultiplier
private readonly IReadOnlyList<string> onlyFor;
private readonly IReadOnlyList<string> notFor;
private readonly IReadOnlyList<string> onlyForSections;
private readonly IReadOnlySet<string>? sections;
public UdcMultiplier(int index, UdcFile file, UdcMultiplierScope shared)
{
@@ -32,6 +34,7 @@ public sealed class UdcMultiplier
onlyFor = file.List($"CountMultOnlyFor{suffix}");
notFor = file.List($"DoNotCountMultOnlyFor{suffix}");
onlyForSections = file.List($"CountMultOnlyForSec{suffix}");
sections = SectionLists.For(file.Text("MultWindowType"));
}
public bool IsDefined => source.Length > 0;
@@ -127,16 +130,24 @@ public sealed class UdcMultiplier
private static string Upper(string text) => text.Trim().ToUpperInvariant();
/// A section multiplier ignores a value that is all digits. N1MM checks the
/// received exchange against the section list the contest names, and a file
/// whose section column also carries the serial numbers the other side of
/// the contest sends — OK/OM DX SSB is one — would otherwise count every
/// serial number as a multiplier. The section lists themselves are not held
/// here.
private static string? SectionName(string text)
/// A section multiplier counts only a value on the list `MultWindowType`
/// names, which is what N1MM checks it against. Without a list — this
/// program holds four of N1MM's, and N1MM has over a hundred — anything
/// that is not all digits counts, so a file whose section column also
/// carries the serial numbers the other side of the contest sends — OK/OM
/// DX SSB is one — does not count every serial number as a multiplier.
private string? SectionName(string text)
{
string section = Upper(text);
return section.Length > 0 && section.All(char.IsAsciiDigit) ? null : section;
if (section.Length == 0)
{
return null;
}
if (sections is not null)
{
return sections.Contains(section) ? section : null;
}
return section.All(char.IsAsciiDigit) ? null : section;
}
private static string? LastLetter(string call)