Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 16:44 Der er 46 kommentarer og
1 løsning

Find tal mellem 1-72

Hej (php-)eksperter
Er der nogen af jer der kan hjælpe mig med at lave et script der finder et felt mellem 1-72 feltet må IKKE kunne findes i tabellen chat_felt under "navnet" feltid

Det må heller IKKE kunne findes i tabellen chat_online under "navnet" felt

Håber i kan hjælpe
Avatar billede myplacedk Nybegynder
08. juni 2003 - 16:51 #1
Forslag:

1) Find de tal, det ikke må være
2) Sortér dem
3) Tæl dem
4) Find et tilfældigt tal mellem 1 og "72 minus tallet fra punkt 3"
5) Gennemgå listen med "forbudte tal". For hver iteration:
  -Hvis tallet er under eller lig med det tilfældige tal: Læg én til det tilfældige tal
  -Hvis tallet er over det tilfældige tal: Afslut løkken
Så skulle den være der...
Avatar billede vesters Nybegynder
08. juni 2003 - 16:56 #2
Lav en rekursiv funktion.

eks. (pseudo-kode)
<?
function findTal() {
    $talDerSkalFindes = rand(1-72);

  if (TestOmTalFindesIForvejen(talDerSkalFindes) == true)
      findTal();
  else
      return $talDerSkalFindes
}
Avatar billede myplacedk Nybegynder
08. juni 2003 - 17:06 #3
Puha, det er en farlig én...
Hvis 71 af de 72 tal er taget, så er der omkring 25% chance for at funktionen kommer til at køre mindst 100 gange.

At lave det rekursivt er ressource-spild. Lav det i det mindste som en while-løkke el. lign., så det eneste der bliver brugt rigeligt af er tid.

while(true) {
  findTal()
  if(talKanBruges()) break;
}
Avatar billede fangel Nybegynder
08. juni 2003 - 17:10 #4
vesters => kan resikerer at lave en uendelig løkke...

*ikke så meget pseudo-kode*
<?php
$harTestet = array();

function checkTal($no){
  $query = mysql_query("SELECT * FROM chat_felt AS f, chat_online AS o WHERE f.navnet = '$no' OR o.navnet ) '$no'") or die(mysql_error());
  if(mysql_num_rows($query) == 0){
    return true;
  else{
    return false;
  }
}
function findTal() {
  global $harTestet;
  $currTal = int(rand(1,72));
  if(checkTal($currTal)){
    return $currTal;
  }
  else{
    $harTestet[] = $currTal;
    findTal();
  }
}

$tal = findTal();

echo $tal; // tal som ikke findes i db og er mellem 1 og 72

?>

---

men myplacedk's forslag er nok bedre, og i hvert fald hurtigere...

Morten
Avatar billede myplacedk Nybegynder
08. juni 2003 - 17:15 #5
dea_pg> Din risikerer også at lave en uendelig løkke, enda også rekursivt... ;-)

Forresten, hvis alle tal er "optaget", så vil min pseudo-kode give tallet "73", så det skal der nok laves en test på mellem punkt 3 og 4. :)
Avatar billede vesters Nybegynder
08. juni 2003 - 17:18 #6
Jeg kan godt lide dit forslag, Morten...Men er der ikke samme risiko, selvom den registrer hvilke der er testet?
Avatar billede fangel Nybegynder
08. juni 2003 - 17:20 #7
jeg skriver også at dit (myplacedk) forslag er bedre!
Avatar billede myplacedk Nybegynder
08. juni 2003 - 17:21 #8
versters > Jo, der er samme risiko. Og selv om den husker hvad den har testet, så kan jeg ikke lige se et sted hvor den information bliver brugt. Det gør heller ikke andet end at aflaste databasen.
Avatar billede myplacedk Nybegynder
08. juni 2003 - 17:23 #9
dea_pg > Yes-yes, det så jeg godt. :)
Det var bare din kommentar om at vesters' forslag kunne lave uendelig løkke, hvorefter du selv viste kode med samme risiko. :)
Avatar billede vesters Nybegynder
08. juni 2003 - 17:23 #10
Men det kommer vel også an på, hvordan felterne bliver fyldt. Det er jo ikke sikkert, at de bliver "optaget" i ASC rækkefølge. Man kunne jo forstille sig, at felter den allerede var gået forbi i sit gennemløb, blev frigjort imens...
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 17:25 #11
Jeg har prøvet vesters script men det kan jeg ikkw få til at virke... Jeg forstår ikke hvordan my-place forslag skal sættes ind..
Avatar billede vesters Nybegynder
08. juni 2003 - 17:31 #12
Nej mit virker ikke, da jeg kalder en funktion, som ikke er skrevet med. Du burde kunne bruge dea_pg's, da koden er mere komplet (men ellers næsten er det samme:-)). Den skal så vidt jeg kan se, bare sættes ind, for at virke...
Avatar billede myplacedk Nybegynder
08. juni 2003 - 17:33 #13
vester> Ja, hvis der kan ske væsentlige ændringer i data på de par milli-sekunder, så skal man selvfølgelig tage hensyn til det. (I øvrigt er min algoritme ligeglad med rækkefølgen...)

www.duzer.dk> Du oversætter punkterne ét af gangen til PHP. Hvis du går i stå, så spørger du bare. (Jeg laver ikke færdig kode til dig, for det lærer du nok ikke noget af, og så spilder jeg bare min tid.)
Avatar billede vesters Nybegynder
08. juni 2003 - 17:36 #14
hov, du har ret omkring rækkefølgen..
Avatar billede fangel Nybegynder
08. juni 2003 - 17:40 #15
muplacedk => du har ret, jeg havde lige glemt en linie... ;)

function findTal() {
  global $harTestet;
  $currTal = int(rand(1,72));
  if(!in_array($currTal, $harTestet)){
    if(checkTal($currTal)){
      return $currTal;
    }
    else{
      $harTestet[] = $currTal;
      findTal();
    }
  }
  else{
    findTal();
  }
}

så kan den ikke blive uendelig!

Morten
Avatar billede myplacedk Nybegynder
08. juni 2003 - 17:45 #16
dea_pg > Hvad sker der, hvis tallet 27 er taget, og rand() (tilfældigvis) giver 27 hver gang. Hvad standser så rekursionen?
Eller, mere realistisk, hvad nu alle tal er taget?
Eller, mere interessant, hvad nu hvis NÆSTEN alle tal er taget? Hvis der kun er ét tal tilbage, så vil der ca. hver 20. skulle 200  rekusioner til, før det sidste tal bliver udtrukket. At have 200 funktioner kørende på samme tid er ikke så smart, især når jobbet gøres bedre med én. ;-)
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 17:47 #17
dea_pq jeg har fået dit til at virke.. men jeg var nød til at lave
$currTal = int(rand(1,72));
om til
$currTal = rand(1,72);

Har det nogen betydning? læg et svar så får du de 20 point
Avatar billede fangel Nybegynder
08. juni 2003 - 17:48 #18
tja... OK, den er stadig ikke god, men den er bedre... ;) siger også bare at den ville være bedre en vesters ;) din er stadig bedre ;)
Avatar billede myplacedk Nybegynder
08. juni 2003 - 17:51 #19
www.duzer.dk > Ja, det virker nu, mens du tester det. Men hvad så når systemet er taget i brug? Du kan evt. læse et par af mine tidligere kommentarer for at se problemet.
Avatar billede vesters Nybegynder
08. juni 2003 - 17:52 #20
Da man's gotta point...
Avatar billede fangel Nybegynder
08. juni 2003 - 17:54 #21
brug myplacedk's da den vil give et bedre resultat ;) prøver lige at lave en bedre:

<?php

function findTal();
  $arr = array();
  $query = mysql_query("SELECT navnet FROM chat_felt A")or die(mysql_error());
  while($data = mysql_fetch_row($query)){
    $key = $data[0];
    $arr[$key] = "taken";
  }
  $query = mysql_query("SELECT navnet FROM chat_online A")or die(mysql_error());
  while($data = mysql_fetch_row($query)){
    $key = $data[0];
    if(!isset($arr[$key])){
      $arr[$key] = "taken";
    }
  }

  for($i=72;$i>0;$i--){
    if(!isset($arr[$i])) break;
  }
  return $arr[$i];
}

$tal = findTal();
echo $tal;
?>

Morten
Avatar billede vesters Nybegynder
08. juni 2003 - 18:00 #22
Kræver denne løsning ikke, at "navnet" er et tal mellem 0 og 72? - eller det er det måske også?
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 18:05 #23
Ja "navnet" er et tal mellem 1-72.. men jeg kan ikke få det til at virke... eller det vil sige at den finder et tal som findes i chat_online
Avatar billede fangel Nybegynder
08. juni 2003 - 18:08 #24
hov, de to A'er i query'erne skal fjernes... ved ikke lige hvorfor det ikke vil, og gidder egentligt ikke bruge tid på det... prøv selv
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 18:22 #25
myplacedk - når der først er mange felter der er noget på siger serveren fejl 500

Er der ikke en der vil hjælpe mig?
Avatar billede myplacedk Nybegynder
08. juni 2003 - 18:37 #26
500? Den skulle ikke kunne opstå blot fordi der er mange fejlter... Hvad står der i fejl-loggen?
Må jeg lige se de to SQL-queries du bruger til at finde de tal er der "optagede"?
Avatar billede myplacedk Nybegynder
08. juni 2003 - 18:37 #27
s/fejlter/felter/
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 18:41 #28
Det var den her jeg brugte..

$harTestet = array();

function checkTal($no){
  $query = mysql_query("SELECT * FROM chat_felt AS f, chat_online AS o WHERE f.feltid = '$no' OR o.felt = '$no'") or die(mysql_error());
  if(mysql_num_rows($query) == 0){
    return true;
  }else{
    return false;
  }
}
function findTal() {
  global $harTestet;
  $currTal = rand(1,72);
  if(!in_array($currTal, $harTestet)){
    if(checkTal($currTal)){
      return $currTal;
    }
    else{
      $harTestet[] = $currTal;
      findTal();
    }
  }
  else{
    findTal();
  }
}
$tal = findTal();



Jeg låste 71 af felterne, og lod et være tomt... så fik jeg fejl 500
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 18:54 #29
Den kommer med den her fejl serveren


Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, casper@realzign.dk and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.


--------------------------------------------------------------------------------

Apache/2.0.43 Server at localhost Port 80
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 18:57 #30
...Men den finder da ud af at det er felt 50 der er ledigt inden den kommer med fejlen... her er et udsnit fra en af mine logfiler

127.0.0.1 - - [08/Jun/2003:18:54:16 +0200] "GET /hemligt/yiir/chat/actions/update.php?felt=50 HTTP/1.1" 200 25
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 18:59 #31
Hov... det gør den alligevellet.. kommer i tanke om at jeg selv klikkede derhen... den starter nemlig med at man kommer ind på chatten... på felt 1... hvis man så opdatere siden kommer den med fejl 500
Avatar billede myplacedk Nybegynder
08. juni 2003 - 19:17 #32
access.log er ret kedelig i denne sammenhæng, kig i error.log i stedet. ;-)
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 19:21 #33
Det er hvad der står i min error log.. jeg slettede alt og gik ind og fik fejlen igen

[Sun Jun 08 18:51:53 2003] [error] [client 127.0.0.1] File does not exist: C:/server/Apache2/htdocs/hemligt/yiir/chat/menu_mellemrum.gif
[Sun Jun 08 18:54:08 2003] [error] [client 127.0.0.1] File does not exist: C:/server/Apache2/htdocs/hemligt/yiir/chat/menu_mellemrum.gif
[Sun Jun 08 18:54:19 2003] [error] [client 127.0.0.1] Premature end of script headers: php.exe
[Sun Jun 08 18:54:30 2003] [error] [client 127.0.0.1] Premature end of script headers: php.exe
[Sun Jun 08 18:54:31 2003] [error] [client 127.0.0.1] Premature end of script headers: php.exe
[Sun Jun 08 19:02:21 2003] [error] [client 127.0.0.1] Premature end of script headers: php.exe
[Sun Jun 08 19:09:54 2003] [notice] Parent: Created child process 248
[Sun Jun 08 19:09:56 2003] [notice] Child 248: Child process is running
[Sun Jun 08 19:09:56 2003] [notice] Child 248: Acquired the start mutex.
[Sun Jun 08 19:09:56 2003] [notice] Child 248: Starting 250 worker threads.
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 20:19 #34
Har prøvet at lave noget selv men det virker hellerikke :





function findnext($tal){

  $query = mysql_query("SELECT * FROM chat_online WHERE rumid = '1' order by felt") or die(mysql_error());
  while($felter = mysql_fetch_array($query)){
$optaget[$felter[felt]] = 'o';
}


  $query1 = mysql_query("SELECT * FROM chat_felt WHERE rumid = '1' order by feltid") or die(mysql_error());
  while($felter1 = mysql_fetch_array($query1)){
$locked[$felter1[feltid]] = 'l';
}


if($tal == "72"){ $tal1 = $tal-71; } else { $tal1 = $tal+1; }
if($locked[$tal1] == 'l' || $optaget[$tal1] == 'o'){ findnext($tal1); } else { return $tal1; }
}








function findtal(){

  $query = mysql_query("SELECT * FROM chat_online WHERE rumid = '1' order by felt") or die(mysql_error());
  while($felter = mysql_fetch_array($query)){
$optaget[$felter[felt]] = 'o';
}


  $query1 = mysql_query("SELECT * FROM chat_felt WHERE rumid = '1' order by feltid") or die(mysql_error());
  while($felter1 = mysql_fetch_array($query1)){
$locked[$felter1[feltid]] = 'l';
}

$tal = rand(1,72);
if($locked[$tal] == 'l' OR $optaget[$tal] == 'o'){ findnext($tal); } else { return "blahh $tal"; }
}

$felt = findtal();
print "$felt";
Avatar billede myplacedk Nybegynder
08. juni 2003 - 20:59 #35
Det går da helt galt det her...

Jeg vil anbefale dig at gå helt tilbage til mit oprindelige forslag. Oversæt stille og roligt punkt 1 til 5 til PHP. Koncentrer dig om ét punkt af gangen, og glem alle de andre imens.

Bare sig til hvis det giver problemer, jeg forlanger ikke andet, end at du prøver.
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 21:03 #36
okey jeg har lavet punkt 1... men hvad mener du med 2) Sortér dem ?-
og hvad mener du med tæl dem... vil det sige plusse alle tallene, eller tælle hvor mange felter man ik kan stå på?
Avatar billede myplacedk Nybegynder
08. juni 2003 - 21:22 #37
Nu ved jeg så ikke hvordan du har lavet punkt et, men hvis du fx. har gjort sådan her:
$niks[$tal] = true;
Altså så du har et array hvor key på hvert element er et tal, der ikke må udtrækkes, så kan du sortere sådan her:
ksort($niks);
Det er væsentligt fordi vi senere tager dem fra en ende af, hvor vi starter med de laveste.

Og med at "tælle" dem mener jeg ganske korrekt at tælle dem, og ikke at lægge dem sammen. ;-)
$antal = count($niks);

ksort() og count() kan du finde her: http://dk.php.net/array
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 21:24 #38
Jeg har kavet punkt 1 og 3 sådan her

$query = mysql_query("SELECT * FROM chat_felt WHERE rumid = '1'") or die(mysql_error());
  $i = mysql_num_rows($query);
$query1 = mysql_query("SELECT * FROM chat_online WHERE rumid = '1'") or die(mysql_error());
  $i1 = mysql_num_rows($query1);


Men det kan jeg se er forkert
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 21:26 #39
Hvordan laver jeg en array med data uf fra en mysql database?
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 21:44 #40
Så er jeg nået så langt her.. ser det rigtigt ud




function findtal(){

$query = mysql_query("SELECT * FROM chat_felt WHERE rumid = '1'") or die(mysql_error());
while($q = mysql_fetch_array($query)) {
$niks[$q[feltid]] = true;
}
$query1 = mysql_query("SELECT * FROM chat_online WHERE rumid = '1'") or die(mysql_error());
while($q1 = mysql_fetch_array($query1)) {
$niks[$q1[felt]] = true;
}

ksort($niks);

}


$felt = findtal();
print "$felt";
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 21:51 #41
Nu er jeg gået i stå... hvordan gennemgår jeg listen med de forbudte tal (punkt 5)






function findtal(){

$query = mysql_query("SELECT * FROM chat_felt WHERE rumid = '1'") or die(mysql_error());
while($q = mysql_fetch_array($query)) {
$niks[$q[feltid]] = true;
}
$query1 = mysql_query("SELECT * FROM chat_online WHERE rumid = '1'") or die(mysql_error());
while($q1 = mysql_fetch_array($query1)) {
$niks[$q1[felt]] = true;
}

ksort($niks);
$antal = count($niks);
$tn = 72-$antal;
$Rtal = rand(1,$tn);

return $Rtal;
}


$felt = findtal();
print "$felt";
Avatar billede myplacedk Nybegynder
08. juni 2003 - 23:16 #42
Det felt, der indeholder det tal, der ikke må udvælges, hedder det "feltid"?
I så fald, så skriv "feltid" i stedet for "*" i dine sql-queries, og ret "$q[feltid]" til "$q['feltid']".
Du behøver ikke tilføje 1-taller til dine variabel-navne. Da du ikke skal bruge de eksisterende variabler længere, kan du blot overskrive dem.

Gennemløb af array:

foreach($niks AS $tal=>$dummy) {
  echo "<p>Tallet '$tal' må ikke kunne udvælges.</p>";
}

"$tal=>$dummy" ser lidt fjollet ud her, men det er også lidt specielt med et array hvor det er nøglerne der er interessande, og selve indholdet er ligegyldigt. :)
Avatar billede www.duzer.dk Nybegynder
08. juni 2003 - 23:44 #43
hvordan kommer jeg så videre så jog får det endelige tal... skal jeg lave et eller andet if($Rtal => $tal){ inde i den der foreach? eller?






function findtal(){

$query = mysql_query("SELECT feltid FROM chat_felt WHERE rumid = '1'") or die(mysql_error());
while($q = mysql_fetch_array($query)) {
$niks[$q['feltid']] = true;
}
$query = mysql_query("SELECT felt FROM chat_online WHERE rumid = '1'") or die(mysql_error());
while($q = mysql_fetch_array($query)) {
$niks[$q['felt']] = true;
}

ksort($niks);
$antal = count($niks);
$tn = 72-$antal;
$Rtal = rand(1,$tn);


foreach($niks AS $tal=>$dummy) {
  echo "<p>Tallet '$tal' må ikke kunne udvælges.</p>";
if($Rtal => $tal){
}

return $Rtal;
}


$felt = findtal();
print "$felt";
Avatar billede myplacedk Nybegynder
09. juni 2003 - 00:15 #44
foreach($niks AS $tal=>$dummy) {
  echo "<p>Tallet '$tal' må ikke kunne udvælges.</p>";
  if($Rtal => $tal){
    $Rtal = $Rtal + 1;
  } else {
    break; // afslut foreach, ingen grund til at fortsætte.
  }
}

Så mangler du vist bare et enkelt tjek:

$tn = 72-$antal;
if ($tn<1) {
  return -1; // Eller hvad du nu synes er bedst.
}

$tn vil give 0, hvis alle 72 muligheder er optaget.
Avatar billede www.duzer.dk Nybegynder
09. juni 2003 - 00:33 #45
Tak for hjælpen men hvis du får tid kan du så ikke forklare hvad den der foreach gør??

Her har du i hvert fald de 20 point.. Tak for hjælpen
Avatar billede myplacedk Nybegynder
09. juni 2003 - 06:47 #46
Jeg kan da prøve om jeg kan give en god forklaring. :)

foreach gennemløber et array, element efter element. Den giver dig mulighed for at arbejde med samtlige elementer, ét af gangen. Fx:

$navne = array("Arne", "Bent", "Christian");
foreach($navne as $navn) {
  echo "<p>Næste navn: $navn</p>";
}

I dette array vil "Arne" automatisk få tildelt nøglen "0", Bent får "1" og Christian får "2". Denne nøgle kan måske være interessant at have adgang til:

foreach($navne as $key=>$navn) {
  echo "<p>Næste navn: $navn (har nummer $key)</p>";
  // $navn indeholder det samme som $navne[$key]
}

"=>" betyder her ikke "lig med eller større end", betragt det som en pil. :)

foreach har en ret underlig syntax, men den er nu meget praktisk. :)

Jeg håber det giver lidt mere mening nu...
Avatar billede www.duzer.dk Nybegynder
09. juni 2003 - 10:54 #47
Okey tak for det.. så forstår jeg det lidt bedre ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester