Gå til innhold

Anbefalte innlegg

Flin foreslo at vi starter en programmeringsoppgavetråd, så her er den. Siden jeg ikke kjenner til den opprinnelige tråden så lager jeg istedet egne regler. Det er ganske enkelt.

  • Noen poster en programmeringsutfordring.
  • Noen finner en løsning på programmeringsutfordring som er elegant nok til å motta "likes". Vinneren er den som får mest likes, folket avgjør.
  • Ny runde og tilbake til punkt 1, dersom punkt 2 er oppfylt. Eller oppgaven ikke mottar en løsning innen ett døgn.

Alle kan poste ny utfordring, men vanskelighetsgraden må avpasses litt for å holde tråden gående. Bruk programmeringsspråk du føler deg komfortabel med eller synes passer for oppgaven.

Første oppgave

Les en CSV fil med utf8 enkoding og vis resultatet i en flott ascii representasjon av dataene. Første linje i filen er overskrift. Radene under kan være tomme eller de kan ha innhold. Filen representerer en ukeplan for en oppdiktet skoleelev, fra mandag til fredag.

(Kopi-og-lim inn kan være feil, så bruk pastebin lenken nederst.)

Mandag,Tirsdag,Onsdag,Torsdag,Fredag
Matte: Oppgave 1-10,Norsk: Stil om Henrik Ibsen,Lesing til naturfagsprøve,Trening,Norsk: Gjøre ferdig stil
Trening,,"Samfunnsfag, kapittel 8-9",Matte: 10-15,


http://pastebin.com/Ragg43MK

  • Liker 2
Lenke til kommentar
Videoannonse
Annonse

Perl.

 

#! /usr/bin/env perl

use strict;
use warnings;
use utf8;
use open qw(:std :utf8);
use Text::CSV;

my $csv = Text::CSV->new( { binary => 1 } );

$csv->parse( my $line = <> );
my @heads = $csv->fields();

format STDOUT_TOP =
--------------------------------------------------------------------------------------------------------------
|@|||||||||||||||||| |@||||||||||||||||||| |@||||||||||||||||||| |@||||||||||||||||||| |@||||||||||||||||||| |
@heads
--------------------------------------------------------------------------------------------------------------
.

my @entries;
format STDOUT =
|^<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|
@entries
|^<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|
@entries
|^<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|
@entries
|^<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|
@entries
|^<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|^<<<<<<<<<<<<<<<<<<<~|
@entries
--------------------------------------------------------------------------------------------------------------
.

while( <> ) {
$csv->parse( $_ );
@entries = $csv->fields();
write;
}
output:

 

~$ perl cal.pl < input
--------------------------------------------------------------------------------------------------------------
| Mandag | Tirsdag | Onsdag | Torsdag | Fredag |
--------------------------------------------------------------------------------------------------------------
|Matte: Oppgave 1-10 |Norsk: Stil om |Lesing til |Trening |Norsk: Gjøre ferdig |
| |Henrik Ibsen |naturfagsprøve | |stil |
--------------------------------------------------------------------------------------------------------------
|Trening | |Samfunnsfag, |Matte: 10-15 | |
| | |kapittel 8-9 | | |
--------------------------------------------------------------------------------------------------------------
Tilpasset for en 80 char bred terminal.

 

edit: noen umiddelbare begrensninger:

 

Dersom noen felter er "for lange"™ vil det knekke. Støtter kun 5 dager, men kan ta villkårlig mange entries.

 

edit2: krever Text::CSV, som bør være pakket for de fleste distroer. Text::CSV har et latterlig ræva interface, hence nokså stygg kode. :/

 

edit3: for å pynte på output kan man alltids gjøre ting som å erstatte linjen mellom dager og entries med ==, fargekoder og mer.

 

edit4: om man ikke egentlig bryr seg om pretty-printing utover columns:

 

csvtool readable < input
Endret av Lycantrophe
Lenke til kommentar

Gjorde ett forsøk uten å bruke CSV parser, i Ruby, og kom fram til følgende løsning:

 

cells = []
widest_cell = 0
File.open (ARGV[0]||"utfordring1.csv") do |f|
  f.each_line do |l|
    line_splitted = "#{l.strip},".scan(/".*?",?|.*?,/)
    cells << line_splitted.map do |ls|
      ls.slice!(-1) if ls.end_with?(',')
      ls.slice!(-1) if ls.end_with?('"')
      ls.slice!(0) if ls.start_with?('"')
      widest_cell = ls.length if ls.length > widest_cell
      ls
    end
  end
end
table_width = widest_cell * cells.first.length + cells.first.length
puts "-" * table_width
cells.each do |row|
  puts row.map{|c| "%-#{widest_cell}s" % c}.join("|")
  puts "-" * table_width
end
Resultat:

 

Y21DNkNC.jpeg

 

Slet mest med å finne ut av det regulære-uttrykket for både sjekk på sitattegn og komma. :p

  • Liker 1
Lenke til kommentar

Ah, du satt det igang ja! Kult.

 

Skal komme med mitt bidrag i løpe av helga eller starten av neste uke. Tenkte litt på om jeg kunne få det til enkelt i Fortran, bare for å irritere alle :p

 

Kanskje den neste oppgaven blir morsom å se i Fortran. :)

 

Vi går videre.

 

Utfordring 2 !!

 

Ganske enkelt, finn det lengste ordet i statsministerens nyttårstale. Talen er å finne på følgende side.

 

Her det mange tilnærmingsmåter. Man kan kopiere talen til en fil og traversere denne, eller man kan lese innholdet direkte fra nettsiden. Jeg foreslår likevel at dere av god høflighet laster ned en kopi av nettsiden og jobber mot denne framfor å gjøre det mot ett live nettsted. Happy programmering.

  • Liker 2
Lenke til kommentar

Ja, det gjør jeg også, men man måtte vel hatt en stygg lambda der du sammenlikner lengdene?

Stygg og stygg.

 

foldr (\str x -> if length str > fst x then (length str, str) else x) (0, "") list
Outputter en ( len, string ) tuple.

 

edit: om man bare skal ha lengden trenger man ikke ta vare på strengen underveis. Man kan også bare ta vare på strengen og sjekke length str > length accu.

Endret av Lycantrophe
Lenke til kommentar

Man behøver ikke å lese teksten fra en lokal fil når man like greit kan traversere DOM-treet direkte. Her utnytter jeg at regjeringsiden bruker jQuery.

var longestWords = $("#Tekstinnhold .imagecontainer").nextAll().text().split(/[^a-zæøåA-ZÆØÅ\-–]+/).sort(
  function(a, b) { 
    return b.length - a.length }
).filter(
  function(value, index, ar) {
    return ar[0].length == value.length
});
console.log(longestWords);

Riktig svar er forøvrig "kunnskapssamfunnet".

Endret av rockPaperScissors()
Lenke til kommentar

Prøver meg på utfordring nr. 2 med PowerShell. I stedet for å lage løsningen så kort eller rask som mulig, er den heller mer solid.

 

Løsningen er høflig; den henter talen automatisk fra serveren og lagrer den lokalt. For å gjøre koden tydelig og lett å lære, har jeg kommentert koden til en viss grad, ikke brukt korte navn/alias'er, og spesifisert navn på alle parametre. Litt feiltesting blir også gjort i tilfelle noe går galt.

 

Det er vanskelig å hente ut ord helt korrekt, fordi man må ta hensyn til regler og unntak, f.eks. for bruk av bindestrek og en/flertallsform i norsk. Siden løsningen min gir korrekt svar, har jeg gjort det enkelt og bare henter ut ord og sammensetninger uten bindestrek, og bryr meg rett og slett ikke om noen regler.

$speechUri = "http://www.regjeringen.no/nb/dep/smk/aktuelt/taler_og_artikler/statsministeren/talerogartikler/2014/statsministerens-nyttarstale.html?id=748426"
$speechFilePath = Join-Path -Path (Get-Location) -ChildPath "speech.txt"
$speechText = $null

if (Test-Path -Path $speechFilePath) {
    # Get cached speech
    $speechText = Get-Content -Path $speechFilePath -Encoding UTF8
}
else {
    # Download speech (HTML document)
    $response = Invoke-WebRequest -Uri $speechUri
    if ($response.StatusCode -ne 200) {
        throw "Failed to download speech"
    }

    # Extract the speech text
    $contentNode = $response.ParsedHtml.getElementById("Tekstinnhold")
    if (-not $contentNode -or -not $contentNode.firstChild -or -not $contentNode.firstChild.firstChild) {
        throw "Couldn't parse document"
    }

    $speechNode = $contentNode.firstChild.firstChild
    # Note: For some reason, using getElementsByTagName() to access each paragraph is very slow, so we'll just remove the stuff we don't need, to speed things up.
    $speechNode.removeChild($speechNode.firstChild) | Out-Null
    $speechText = $speechNode.innerText

    # Cache the speech
    $speechText | Set-Content -Path $speechFilePath -Encoding UTF8
}

# Extract words from speech
$speechWords = $speechText |
    Select-String -Pattern "\w+" -AllMatches |
    Select-Object -ExpandProperty Matches |
    Select-Object -ExpandProperty Value

$sortedWords = $speechWords | Sort-Object -Property Length -Descending
$longestWord = $sortedWords | Select-Object -First 1
$otherLongWords = $sortedWords | Select-Object -First 5 -Skip 1

$longWordFormat = "  {0} ({1} characters)"
Write-Output "Longest word:"
Write-Output ($longWordFormat -f $longestWord, $longestWord.Length)
Write-Output "Other long words:"
$otherLongWords | ForEach-Object { Write-Output ($longWordFormat -f $_, $_.Length) }

Output:

Longest word:
  kunnskapssamfunnet (18 characters)
Other long words:
  behandlingstilbud (17 characters)
  lektorutdanningen (17 characters)
  Rederiforbundets (16 characters)
  ingeniørstudiet (15 characters)
  konfliktområder (15 characters)

PS: Jeg skriver alltid kode og UI-tekst på engelsk, og oversetter evt. teksten til andre språk.

Endret av ahw_
  • Liker 2
Lenke til kommentar

Jeg tror noen pekte seg ut på liker-skalaen. Gjennomtenkt, og antagelig det lengste PowerShell-skriptet jeg har lest så langt. :wee:

 

Nå videre..

 

post-307986-0-04279100-1409806189_thumb.jpg

 

Jeg er spent på hvordan denne løses.

 

Oppgaven består i å bytte ut overskrifter og ledetekster på nrk.no med nyheter som er lest fra seher.no. Dette gjør vi naturligvis ikke på NRK sine servere om noen tenker det, ettersom det ikke ville vært en hyggelig ting å gjøre. Underholdningspoeng for skjermdump av resultatet.

 

[Redigert: "Runde 3" bildet er lastet opp på diskusjon.no etter tilbakemelding om at det kunne være lurt å gjøre det slik.]

Endret av rockPaperScissors()
  • Liker 1
Lenke til kommentar

@Django og jeg har løst utfordring nr. 3 litt på samme måte, men ikke helt. Jeg skal forklare hvorfor jeg valgte slik.

 

Demo:

http://c3proxy.diskusjonno.steffenl.com

 

Hvis du ikke får tilgang til demoen er det fordi jeg glemte å sette opp DNS tidsnok. Venter du litt kommer den nok opp.

 

Skjermdump:
post-224066-0-68642500-1409852201_thumb.png

 

Kode:

Git-repo:

https://github.com/SteffenL/web-proxy-experiment/tree/develop

 

Det er flere filer som dere kan see i repo'en, men her er hoved-skriptet med mest innmat:

https://github.com/SteffenL/web-proxy-experiment/blob/develop/app/WebProxy.php

 

Generelt om løsningen min:

Utfordring nr. 3 kan løses på en del forskjellige måter, f.eks. med

  • Et «brukerskript» for Greasemonkey og Tampermonkey: Skriptet sender en ny web-request til seher.no når du besøker nrk.no. Det kan kanskje være et merkbart etterslep slik at den originale teksten først vises (med mindre skriptet skjuler den) en liten stund før teksten blir erstattet, men det er jeg ikke helt sikker på.
  • En selvstending mini-nettleser som må lastes ned kjøres på brukerens PC/mobil.
  • En HTTP proxy-server som fungerer i alle operativsystemer og nettlesere som har muligheten til å bruke proxy. Man kan f.eks. bruke proxpy til å lage noe kjapt og enkelt i Python.
  • En nettbasert proxy som f.eks. hidemyass.com. Denne varienten er et greit alternativ til en ordentlig proxy-server i mange tilfeller, og vil fungere i hvilken som helst standard nettleser.

Jeg har valgt den siste løsningen i listen over fordi det sparer brukere tid, fungerer overalt, gir fortsatt brukeren fordelen med CDN, og tjenesten kan oppdateres når som helst i bakgrunnen. I tillegg kan vi unngå å kjøre alt gjennom proxy'en, så vi kan spare båndbredde.

Når man lager en slik proxy har man et lite problem med sikkerhet/HTTPS/SSL fordi klienten ikke lenger har en sikker og direkte tilkobling mot nrk.no og seher.no. I det minste kan man ha en sikker tilkobling mot selve proxy'en, så har proxy'en en sikker tilkobling mot den endelige serveren. I dette tilfellet er det heldigvis ikke nødvendig å ta dette i betraktning fordi HTTPS ikke er nødvendig.

Andre ting som vanligvis bør tas i betrakting er f.eks. cookies som sendes til og fra klienten og nrk.no/seher.no; igjen er ikke dette nødvendig fordi det ikke finnes noe sted å logge seg inn for lesere.

Språket PHP valgte jeg fordi det er lett å komme i gang med, også for nybegynnere.

Mer konkret om løsningen:
Dette er en mer komplett og solid web-proxy (men ikke så solid at den bør tas i bruk). Med litt mer arbeid kan faktisk min løsning brukes til å surfe anonymt, akkurat som med andre web-proxy'er. Sidene fortsetter å fungere via proxy'en når man trykker på lenker (på nrk.no), og det er lagt til rette for å endre på flere individuelle sider.

Jeg demonstrerer at alle sidene kan endres, med å legge inn litt «cred» til meg selv øverst.

Artiklene på førstesiden på nrk.no blir erstattet med artikler fra førstesiden på seher.no etter reglene, og erstatter i tillegg bildet (ikke noe spesielt ekstra arbeid). Aspect ratio'en på bildene blir fikset, men størrelsen på selve bildene blir ikke helt perfekte.

 

Jeg har lagt (litt) til rette for at artikler fra seher.no kan hentes fra deres RSS feed, men merk at den bare gir oss 10 artikler, og er derfor nesten ubrukelig.

Kvaliteten på koden kan det jobbes en god del (hvis jeg orker), men det fungerer tilsynelatende. :)

En liten vri er at artiklene fra seher.no plasseres tilfeldig, slik at man alltid får se nytt (eller gammelt) innhold. Når alle artiklene fra seher.no er brukt opp, brukes de om igjen (fortsatt tilfeldig). Dette gjør at man ikke ser de samme artiklene før man nesten må.

Endret av ahw_
  • Liker 3
Lenke til kommentar

Jeg hadde i utgangspunktet lagt til bilder på min også, men fjernet det igjen siden halvparten av poenget var vel at den skulle vise bildene fra NRK og titlene til Se og Hør (noe som gjør det morsommere). Kunne også laget en tilsvarende løsning som du har gjort. Men tenker det kanskje er best om vi holder oss til røttene av utfordringen. Hvis man overkompliserer svaret til oppgaven vil mange ikke ha tid/mulighet til å delta, er kanskje greit å følge "KISS" konseptet på fremtidige løsninger. Litt av poenget er vel at vi skal løse det samme problemet på ulike måter/språk. Kudos for løsningen din altså!

Endret av Django
Lenke til kommentar

Jeg hadde i utgangspunktet lagt til bilder på min også, men fjernet det igjen siden halvparten av poenget var vel at den skulle vise bildene fra NRK og titlene til Se og Hør (noe som gjør det morsommere). Kunne også laget en tilsvarende løsning som du har gjort. Men tenker det kanskje er best om vi holder oss til røttene av utfordringen. Hvis man overkompliserer svaret til oppgaven vil mange ikke ha tid/mulighet til å delta, er kanskje greit å følge "KISS" konseptet på fremtidige løsninger. Litt av poenget er vel at vi skal løse det samme problemet på ulike måter/språk. Kudos for løsningen din altså!

 

Må innrømme at jeg føler meg litt teit nå. :blush: Var ikke meningen å gjøre det altfor komplisert eller gi et inntrykk av at jeg tror jeg kjempeflink, men jeg klarer bare ikke alltid å la noe jeg kan forbedre (koden min) være. Det er fortsatt ikke perfekt etter min standard, men det er ikke poenget, det er jeg klar over. Tror jeg kan si meg enig i at jeg kanskje ikke bør få ekstrapoeng.

 

Jeg lar bildene i min varient være denne gangen uansett om det var galt eller ei, så er løsningene mer ulike i hvert fall. :)

Endret av ahw_
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...