Programming C# Checksum van reeks cijfers in een .txt bestand

Yusifer

Well-known member
Crowdfunder FE
De bedoeling is om een WPF project te maken om met C# eerst een .txt bestand te laden in een textbox. Dit heb ik al gedaan.

Dit .txt bestand bevat een lange reeks aan cijfers (geen letters aanwezig). Het is de bedoeling dat ik de checksum van deze reeks weergeef. Checksum is sommeren van alle cijfers die hetzelfde zijn als het daaropvolgend cijfer in de reeks.

Bv. "1111" checksum is 4 want elk cijfer is hetzelfde. "1234" checksum is 0 want geen enkel cijfer is hetzelfde als z'n opvolger.

Ik heb al wat zitten googlen maar geen duidelijke antwoorden terug te vinden.
 
De beschrijving is een beetje onduidelijk. 1111 is 4? De laatste 1 heeft geen opvolger, is het dan niet 3? Of is het zodra er eenzelfde paar cijfers is, dat je ze allemaal opteld? Of is het een circulaire reeks? Wat is 11211 bijvoorbeeld?

Zoek je verder een algoritme om dit op te lossen? Of zit je ook met code om stukjes te parsen/de oplossing weer te geven?
 
De beschrijving is een beetje onduidelijk. 1111 is 4? De laatste 1 heeft geen opvolger, is het dan niet 3? Of is het zodra er eenzelfde paar cijfers is, dat je ze allemaal opteld? Of is het een circulaire reeks? Wat is 11211 bijvoorbeeld?

Zoek je verder een algoritme om dit op te lossen? Of zit je ook met code om stukjes te parsen/de oplossing weer te geven?

Ik ben in mijn post vergeten te vermelden dat de cijferreeks een ringbuffer is (m.a.w. het laatste cijfer in de reeks wordt gevolgd door het eerste cijfer in de reeks).

Ook 4 voorbeelden volgens de uitleg:

- 1122: Checksum is 3 want het eerste cijfer is hetzelfde als het tweede cijfer en het derde cijfer is hetzelfde als het vierde cijfer (1 + 2 = 3)
- 1111: Checksum is 4 want 1ste cijfer is zelfde als 2de cijfer, 2de cijfer is zelfde als 3de, en 3de is hetzelfde als 1ste cijfer (1 + 1 + 1 +1 = 4)
- 1234: Checksum is 0 want geen cijfer is hetzelfde als zijn opvolger
- 91212129: Checksum is 9 want enig cijfer dat gevolgd wordt door hetzelfde cijfer is het laatste cijfer in de reeks (9 = 9)

Als ik de logica begrijp, heeft 11211 een checksum van 2 want 1ste cijfer is zelfde als 2de cijfer, maar derde cijfer heeft geen opvolger (1 + 1 = 2)

En de vraag is dan om deze logica toe te passen op een vrij grote tekenreeks (te groot voor int64 of long). De oplossing voor deze tekenreeks is me al gegeven, de moeilijkheid zit erin deze logica te programmeren en ik ben niet zeker hoe.
 
Ok, volgens je uitleg zou ik eigenlijk 3 verwachten voor 11211, met de drie cijfers in [] opgeteld: [1]12[1][1].

Is het dan niet iets als (EDIT: gvd rotte formatting, ik moet er ook even tussenuit dus hopelijkt helpt het al wat):

if (digits.count() < 2) return 0;
int sum = 0;
for (int i = 0; i < digits.count() ; i++)
if (digits[ i ] == digits[(i + 1) % digits.count()])
sum += digits[ i ];
return sum;
 
Laatst bewerkt:
Ok, volgens je uitleg zou ik eigenlijk 3 verwachten voor 11211, met de drie cijfers in [] opgeteld: [1]12[1][1].

Is het dan niet iets als (EDIT: gvd rotte formatting, ik ben er even tussenuit):

if (digits.count() < 2) return 0;
int sum = 0;
for (int i = 0; i < digits.count() ; i++)
if (digits[ i ] == digits[(i + 1) % digits.count()])
sum += digits[ i ];
return sum;

Eh zou idd 3 moeten zijn, mn brain is fried. :D

Met deze formule ben ik er nog niet helemaal. De cijferreeks is te lang voor een int of een long (wel begot 2000 cijfers ofzo), ik kan het wel in een double opslaan maar dan geeft hij het oneindig-teken als resultaat.

Voelt toch echter aan als een stap dichterbij de oplossing. Bedankt voor de hulp!
 
Laatst bewerkt:
Ik ben in mijn post vergeten te vermelden dat de cijferreeks een ringbuffer is (m.a.w. het laatste cijfer in de reeks wordt gevolgd door het eerste cijfer in de reeks).

Ook 4 voorbeelden volgens de uitleg:

- 1122: Checksum is 3 want het eerste cijfer is hetzelfde als het tweede cijfer en het derde cijfer is hetzelfde als het vierde cijfer (1 + 2 = 3)
- 1111: Checksum is 4 want 1ste cijfer is zelfde als 2de cijfer, 2de cijfer is zelfde als 3de, en 3de is hetzelfde als 1ste cijfer (1 + 1 + 1 +1 = 4)
- 1234: Checksum is 0 want geen cijfer is hetzelfde als zijn opvolger
- 91212129: Checksum is 9 want enig cijfer dat gevolgd wordt door hetzelfde cijfer is het laatste cijfer in de reeks (9 = 9)

Als ik de logica begrijp, heeft 11211 een checksum van 2 want 1ste cijfer is zelfde als 2de cijfer, maar derde cijfer heeft geen opvolger (1 + 1 = 2)

En de vraag is dan om deze logica toe te passen op een vrij grote tekenreeks (te groot voor int64 of long). De oplossing voor deze tekenreeks is me al gegeven, de moeilijkheid zit erin deze logica te programmeren en ik ben niet zeker hoe.

Die 91212129 moet toch ook als oplossing 1 hebben?
Kun je het tekstbestand niet per char inlezen, bijhouden, volgend char inlezen, vergelijken en dan loopen? Eerste char moet je bijhouden en op einde nog checken met die eerste.
 
Eh zou idd 3 moeten zijn, mn brain is fried.

Met deze formule ben ik er nog niet helemaal. De cijferreeks is te lang voor een int of een long (wel begot 300 cijfers ofzo), ik kan het wel in een double opslaan maar dan geeft hij het oneindig-teken als resultaat.

Voelt toch echter aan als een stap dichterbij de oplossing. Bedankt voor de hulp!
Aight! Als je nog hulpt wilt, vraag gerust.

Enige wat ik niet begrijp: cijferreeks te lang, ik dacht dat het een String/char array was. Dat zou je gewoon moeten kunnen indexeren (en 2000 tekens in geheugen is niks).
 
Die 91212129 moet toch ook als oplossing 1 hebben?
Kun je het tekstbestand niet per char inlezen, bijhouden, volgend char inlezen, vergelijken en dan loopen? Eerste char moet je bijhouden en op einde nog checken met die eerste.
Het is 9 omdat je het cijfer zelf moet nemen en optellen, niet het aantal tellen.
 
Aight! Als je nog hulpt wilt, vraag gerust.

Enige wat ik niet begrijp: cijferreeks te lang, ik dacht dat het een String/char array was. Dat zou je gewoon moeten kunnen indexeren (en 2000 tekens in geheugen is niks).

Het is een string array ja, omdat ik een .txt file leest.
C#:
string[] text = System.IO.File.ReadAllLines(@"..\checksum.txt");

Ik heb een textbox voorzien om deze cijferreeks weer te geven (puur voor overzicht, is niet noodzakelijk)
C#:
foreach (var character in text)
{
txtCheckSum.Text = character;
}

Dan heb ik uw idee toegepast.
C#:
double sum = 0; (als ik int of long gebruik krijg ik error dat de waarde te groot is voor een int)
           for (int i = 0; i < text.Count(); i++)
            {
                if (text[i] == text[(i + 1) % text.Count()])
                {
                    sum += double.Parse(text[i]);
                }
            }

De sum zou 1171 moeten zijn, als de error zegt dat de waarde te groot is voor een int ben ik dus iets fouts aan het doen in de berekening.
 
Laatst bewerkt:
Ben geen C# pro, maar zie dat `int.Parse` ook bestaat, dus die zou je kunnen gebruiken. En dan een int/long sum? Gok dat je de error krijgt omdat je een double probeert op te tellen bij een int/sum.

EDIT: oh, of -> je indexed de text array, wat elk een volledige lijn van de input is (i.e. alle cijfers op 1 lijn). Dus die parsen is inderdaad veel te groot voor int/long. Je moet de karakters van 1 lijn indexeren.
 
Ben geen C# pro, maar zie dat `int.Parse` ook bestaat, dus die zou je kunnen gebruiken. En dan een int/long sum? Gok dat je de error krijgt omdat je een double probeert op te tellen bij een int/sum.

Ah nee, bij het gebruiken van een double krijg ik "infinity" als resultaat.

Bij het gebruiken van int krijg ik error dat de waarde te groot of te klein is voor een int. Zelfde verhaal bij long. Enkel double omzeilt dit probleem.
 
Ah nee, bij het gebruiken van een double krijg ik "infinity" als resultaat.

Bij het gebruiken van int krijg ik error dat de waarde te groot of te klein is voor een int. Zelfde verhaal bij long. Enkel double omzeilt dit probleem.
Heb net nog een edit gedaan, denk dat dat het probleem is :unsure:
 
Kan het niet simpeler?
Uw textfile inlezen via streamreader. Dan overloop je elk character.
Parsen naar int, en bijhouden in variable & checken als uw volgende character hetzelfde is. Zoja, bijtellen, zoniet skippen.
los uit het koppie, dus mogelijks met syntax fouten
int checksum =0;
int vorigGetal = 0;
bool isReeks = false;

StreamReader reader = new StreamReader(@"C:\Users\...\checksum.txt");
while (!reader.EndOfStream)
{
int huidigGetal = 0;
int.TryParse(reader.Read(), out huidigGetal);

if(huidigGetal == vorigGetal)
{
checksum += huidigGetal;
if(!isReeks)
checksum += vorigGetal; //eerste getal van opeenvolgende reeks ook bijtellen

isReeks = true;
}
else
isReeks = false;

vorigGetal = huidigGetal;
}
reader.Close();
reader.Dispose();
 
Het is een string array ja, omdat ik een .txt file leest.
C#:
string[] text = System.IO.File.ReadAllLines(@"..\checksum.txt");

Ik heb een textbox voorzien om deze cijferreeks weer te geven (puur voor overzicht, is niet noodzakelijk)
C#:
foreach (var character in text)
{
txtCheckSum.Text = character;
}

Dan heb ik uw idee toegepast.
C#:
double sum = 0; (als ik int of long gebruik krijg ik error dat de waarde te groot is voor een int)
           for (int i = 0; i < text.Count(); i++)
            {
                if (text[i] == text[(i + 1) % text.Count()])
                {
                    sum += double.Parse(text[i]);
                }
            }

De sum zou 1171 moeten zijn, als de error zegt dat de waarde te groot is voor een int ben ik dus iets fouts aan het doen in de berekening.
Uw text[i+1] gaat falen als ge in uw laatste itteratie zit
 
Kan het niet simpeler?
Uw textfile inlezen via streamreader. Dan overloop je elk character.
Parsen naar int, en bijhouden in variable & checken als uw volgende character hetzelfde is. Zoja, bijtellen, zoniet skippen.
los uit het koppie, dus mogelijks met syntax fouten
Gwn inlezen als string. Dacht de readAllText en erna den .ToCharArray().
Performantiegewijs zo je kunnen opteren voor een for loop tov foreach. Maar dat verschil zal banaal zijn.
Na je loop gewoon den eerste en laaste index met elkaar vergelijken en eventueel optellen met je resultaat.
 
Uw text[i+1] gaat falen als ge in uw laatste itteratie zit
Als ie mijn eerste lijn code vergeten is wel ja ( if (digits.count() < 2) return 0; ). Verder denk ik niet dat het veel simpeler kan, enkel anders geschreven (bvb. gebruik van boolean zoals hierboven).
 
Als ie mijn eerste lijn code vergeten is wel ja ( if (digits.count() < 2) return 0; ). Verder denk ik niet dat het veel simpeler kan, enkel anders geschreven (bvb. gebruik van boolean zoals hierboven).
De laatste index met de eerst ook niet vergeten te doen, na de loop 😁
 
De laatste index met de eerst ook niet vergeten te doen, na de loop 😁
Dat gebeurt al, wanneer je modulair indexed (dus (i + 1) % count). Zie nu dat ik je opmerking verkeerd interpreteerde.

De laatste iteratie verglijk je index (count - 1) en (count % count, i.e. 0). Dus wordt gewoon gedaan de laatste stap van de loop.
 

Vergelijkbare onderwerpen

Terug
Bovenaan