Hackerboard WikiHaboBlog

[HaBo]

 
Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann.

Aufgabe Nr. 1: Primzahlenpaare

Diskussion: Aufgabe Nr. 1: Primzahlenpaare im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Ein wunderschönes Ausgabelayout habe ich nicht, aber es klappt ganz gut wenn man denn genung RAM hat, wenn nicht muss ...

Antwort
Alt 30.03.07, 21:43   #16 (permalink)
 
Benutzerbild von Stein
 
Registriert seit: 10.10.05
Stein Leistung: Facit NTK
Stein eine Nachricht über ICQ schicken
Likes: 0
Standard


Ein wunderschönes Ausgabelayout habe ich nicht, aber es klappt ganz gut wenn man denn genung RAM hat, wenn nicht muss man alles in MYSQL Tabellen anstatt von Array speichern. Hier das ganz in PHP:

PHP-Code:
<?php
/*Das Sieb des Aristotoes:
"Man muss nicht rechnen können um Primzahlen zufinden nur zählen." Normaler Weiser schreibt man alle Zahlen auf ein Blatt und fängt bei 2 an: 2
 wir nicht durchgestrichen, zwei weiter (4) wird durch gestrichen usw. dann mit 3.*/

$zahlen = array(0);//Beginn der Berechnung
for ($i=1;$i<10000;$i++){
    
$zahlen[$i] =1;
}
for(
$j=2;2*$j<10000;$j++){//"siebt" alle Zahlen bis zu Hälfte
    
if ($zahlen[$j] == 1){//nur Vielfach von Primzahlen werden druchgestrichen wenn 
        
for($k=$j;$k<10000;){ //ich alle Vielfach von 2 habe brauche ich die von 4 nicht.
            
$k=$k+$j;
            
$zahlen[$k] = 0;//Vielfach sind keine Primzahlen
        
}
    }        
}    
//Ende der Berechnung
//Beginn der Ausgabe
$primzahl = array(0);
for(
$l=1;$l<10000;$l++){
    if(
$zahlen[$l]==1){
        echo 
$l."<br>";
        
$primzahlen[]= $l;//Menge aller Primzahlen
    
}
}
//Jetzt die Primzahlpaarerweiterung:
echo "Primzahlpaare sind:<br>";
for(
$m=1;$m<count($primzahlen);$m++){
    if (
$primzahlen[$m+1]-$primzahlen[$m] == 2){
        
$mpluseins $m +1;
        echo 
"$primzahlen[$m] | $primzahlen[$mpluseins] <br>";//mit [$m+1] hat leider nicht geklappt
    
}
}
?>
__________________
Steinhagelvoll
Stein ist offline   Mit Zitat antworten
Alt 08.04.07, 22:37   #17 (permalink)
 
Registriert seit: 02.02.07
my2$/100 Leistung: Facit NTK
Likes: 0
Standard naiver Algorithmus in D

Es sieht fast aus wie C++. Ich habe es auch ursprünglich damit geschrieben. Die Eingabe ist aber viel robuster.

Die vorgehensweise ist naiv. Die einzigen Optimierungen sind:
  • Prüfung nur bis Wurzel(n)
  • gerade Teiler und gerade (Prim-)Zahlen werden ignoriert
Code:
import std.stream;
import std.math;
import std.stdio;
import std.string;

void eingabe(out uint min, out uint max)
{
    char input[6];
    do
    {
        writef("Untere Grenze: ");
        scanf("%s", &input);
        min = cast(uint) atoi(input);
        writef("Obere Grenze: ");
        scanf("%s", &input);
        max = cast(uint) atoi(input);
    }
    while(min<3 || max<=min);
}

bit isPrime(uint zahl)
{
    // Teiler bis wurzel(zahl) auf glatte Teilung prüfen
    // alle Vielefache von 2 können ignoriert werden
    uint grenze = cast(uint) sqrt(cast(real)zahl);

    for(uint i=3; i<=grenze; i+=2)
    {
        if(zahl%i==0)
           return false;
    }
    return true;
}

int main(char[][] args)
{
    bit last_was_prime = false;
    uint min,max;

    // Bereich eingeben
    eingabe(min,max);

    // Alle ungeraden Zahlen im Bereich prüfen
    // Bei der ersten ungeraden anangen
    for(uint i = min%2==0 ? min+1:min; i<=max; i+=2)
    {
        if(isPrime(i))
        {
            if(last_was_prime)
                writefln("%5d\t%5d", i-2, i);

            last_was_prime = true;
        }
        else
        {
            last_was_prime = false;
        }
    }
    return 0;
}
War mein erster D Test.
my2$/100 ist offline   Mit Zitat antworten
Alt 21.05.08, 02:39   #18 (permalink)
 
Registriert seit: 21.04.08
Ook! Leistung: Facit NTK
Likes: 0
Standard

Meine Groovy-Lösung

Code:
List doIt(start, end){
	couples = []
	
	for(i in start..end)
		if(isPrim(i) && isPrim(i+2))
			couples.add(i +" "+ (i+2))
	return couples
}

Boolean isPrim(num){
	for(x=2; x<=Math.sqrt(num); x++){
		if(num%x == 0)
			return false
	}
	return true
}

println doIt(3, 50) // 3 - 5, 5 - 7, 11 - 13, 17 - 19, 29 - 31, 41 - 43
Eine weitere Groovy-Variante... meiner Meinung nach sehr elegant
Code:
def doIt(start, end){
	return (start..end).findAll { n -> (start..<n).every { z -> n%z != 0 && (n+2)%z != 0 } }
}

doIt(3, 50).each { n -> print "${n} - ${n+2}, " } // 3 - 5, 5 - 7, 11 - 13, 17 - 19, 29 - 31, 41 - 43
Gruß
Felix

EDIT
Hier noch eine sehr schöne Scala Variante:
Code:
object PrimeNumbers extends Application {
  def isPrime(n : Int) : Boolean =
    List.range(2, n-1).filter(n%_ == 0).length == 0

  var list = List.range(3,50).filter(n => isPrime(n) && isPrime(n+2))
  list.foreach(n => println(n +" - "+ (n+2)))
}
Ook! ist offline   Mit Zitat antworten
Alt 14.04.09, 14:40   #19 (permalink)
 
Benutzerbild von pytohn
 
Registriert seit: 28.03.09
pytohn Leistung: Facit NTK
Likes: 0
Standard

Hier eine Lösung in Python 3:


Code:
from math import *

def primzahl(x):
prim = True
for t in range(2, (x-1)):
if x/t == x//t:
prim = False
break
if prim == False or x == 1:
return False
else:
return True

try:
start = input("Startwert: ")
ende = input("Endwert: ")
start, ende = int(start), int(ende)
for i in range(start, (ende-2)):
if primzahl(i):
if primzahl(i+2):
output = "%d t %d" %(i, (i+2))
print(output)

except:
print("Leider trat ein Fehler auf!")
pytohn ist offline   Mit Zitat antworten
Alt 02.05.09, 15:46   #20 (permalink)
 
Registriert seit: 16.04.09
Eggmanne Leistung: Facit NTK
Likes: 0
Standard

Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  unsigned int number=7;                  //zu überprüfende,incrementirende zahl
  unsigned int i=3;                       
  unsigned short int counter=4;           //zählt die menge der primzahlen
  unsigned int last_prime=5;                    
  
//die ersten primzahlen werden geschenkt

  printf("%d , %d\n",3,5);
  for(;counter<=50;number+=2){
    for(i=3;number%i!=0 && i<=number/2;i+=2){   
    }

//wenn for schleife komplett durchgelaufen ist,
//also i>=number/2 dann ist number== prim   

    if(i>=number/2){        
      if(number==(last_prime+2))
        printf("%u , %u\n",last_prime,number);
      counter++;
      last_prime=number;
    }
  }
  
  getch();	
  return 0;
}
und noch ne schnelle c lösung
Eggmanne ist offline   Mit Zitat antworten
Alt 03.05.09, 15:34   #21 (permalink)
 
Benutzerbild von Stein
 
Registriert seit: 10.10.05
Stein Leistung: Facit NTK
Stein eine Nachricht über ICQ schicken
Likes: 0
Standard

Da ich einiges an Langeweile hatte und sowie so Scheme üben muss:
Code:
(define (is_prim n teiler)
  (cond ((>(* teiler teiler) n) #t)
        ((= (remainder n teiler)  0) #f)
        (else (is_prim n (+ teiler 1)))))
(define (main n  end)
  (if (<= n end )(and
      (if (and (is_prim n 2) (is_prim (+ n 2) 2))
      (and (write n) (write "+")(write (+ n 2)) (write "-->")))
      (main (+ n 2) end))))
Damit habe ich wohl das kürzeste

edit:
Code:
(define (is_prim n teiler)  (cond ((>(* teiler teiler) n) #t)   ((= (remainder n teiler)  0) #f)   (else is_prim n (+ teiler 1))))) (define (main n  end)  (if (<= n end )(and     (if (and (is_prim n 2) (is_prim (+ n 2) 2))   (and (write n) (write "+")(write (+ n 2)) (write "-->"))) (main (+ n 2) end))))
__________________
Steinhagelvoll
Stein ist offline   Mit Zitat antworten
Alt 03.05.09, 18:19   #22 (permalink)
Senior Member
 
Registriert seit: 03.09.05
Lesco Leistung: Facit NTK
Likes: 0
Standard

Zitat:
Original von Stein
Damit habe ich wohl das kürzeste
Die gepostete Groovy- und die Scala-Variante ist kürzer.

Hier nochmal eine Lösung in Haskell mit besserem Primzahlsieb(nur durch Primzahlen teilen):
Code:
isPrime x = all ((/=0) . (x `mod`)) . takeWhile ((<=x) . (^2)) $ primes

primes = 2:[x | x <- [3,5..], isPrime x]

paare n m = map (\x -> (x,x+2)) $ filter ((`elem` ps) . (+2)) ps
    where ps = takeWhile (<=m-2) . dropWhile (<=n) $ primes
Lesco ist offline   Mit Zitat antworten
Alt 04.05.09, 12:07   #23 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 156
Standard

Prolog mit einem Sieb:
Code:
notprim(N,E):-E=\=N, mod(E,N)=:=0.
primlist([],[]).
primlist([E|T],[E|R]):- exclude(notprim(E),T,ExList), primlist(ExList,R),!.

filter(_,[_]).
filter(Min,[E,E2|T]):- (E>=Min,2 is E2-E,writeln(E-E2),true),filter(Min,[E2|T]),!.
paare(From,To):-numlist(2,To,List),primlist(List,Prims),filter(From,Prims).
bzw. "größenoptimiert" (aber weniger gut lesbar )
Code:
notprim(N,E):-E=\=N, mod(E,N)=:=0.
primlist([],[]). primlist([E|T],[E|R]):- exclude(notprim(E),T,ExList), primlist(ExList,R),!.
filter(Min,[E,E2|T]):- (E>=Min,E2-E=:=2 -> writeln(E-E2);true),filter(Min,[E2|T]),!.
paare(From,To):-numlist(2,To,List),primlist(List,Prims),filter(From,Prims).
Ausgabe:
Zitat:
?- paare(1,30).
3-5
5-7
11-13
17-19
fail.
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 02.11.09, 14:02   #24 (permalink)
 
Benutzerbild von pytohn
 
Registriert seit: 28.03.09
pytohn Leistung: Facit NTK
Likes: 0
Standard Scheme-Lösung

Hier noch eine Schemelösung:

Code:
(define primzahl
  (lambda (n t)
    (if (> n 1)
        (if (and (>= t 2) (< t n))
            (if (= (modulo n t) 0)
                #f
                (primzahl n (+ t 1)))
            #t)
        #f)))

(define paare
  (lambda (min max)
    (if (<= (+ min 2) max)
        (if (primzahl min 2)
            (if (primzahl (+ min 2) 2)
                (begin (write min) (display "\t") (write (+ min 2)) (display "\n") (paare (+ min 1) max))
                (paare (+ min 1) max))
            (paare (+ min 1) max))
        (display "Ende erreicht!"))))

; Beispiel-Aufruf (Paare von 1 bis 30):
; (paare 1 30)
Wenn ihr noch Tipps habt, wie ich das Programm verbessern kann, bitte eine PN schicken. Ich fange gerade erst mit Scheme an.
pytohn ist offline   Mit Zitat antworten
Alt 13.12.09, 23:13   #25 (permalink)
 
Benutzerbild von Chris_XY
 
Registriert seit: 01.07.05
Chris_XY Leistung: Z3
Likes: 3
Standard

Auch noch einmal von mir in Ada.

Eigentlich wollte ich ja auch das Sieb des Erastosthenes nutzen, aber als ich dann gesehen habe, dass man in Ada keine Schrittweite für For-Schleifen angeben kann, hatte ich da auch keine Lust mehr. Deshalb mit recht ineffizienter Primzahlbestimmung (Prüfen auf Rest = 0 für Ungerade Teiler bis Zahl/2). Am Ende ist aber immer noch die Ausgabe das langsamste.

Code:
with Ada.Text_IO, Ada.Integer_Text_IO;

procedure Primzahlpaare is
   Eingabe : Positive;

   function Ist_Paar (Zahl1, Zahl2 : Positive) return Boolean is
   begin
      if Zahl1 mod 2 /= 0 then
         for Zaehler in 3 .. Zahl1 / 2 loop
            if Zahl1 mod Zaehler = 0 or Zahl2 mod Zaehler = 0 then
               return False;
            end if;
         end loop;
      end if;
      return True;
   end Ist_Paar;

   procedure Paare_Ausgeben (Eingabe : Positive) is
   begin
      for Zaehler in 3 .. Eingabe loop
         if Zaehler mod 2 /= 0 then
            if Ist_Paar (Zaehler, Zaehler + 2) then
               Ada.Integer_Text_IO.Put (Zaehler, 1);
               Ada.Text_IO.Put (" - ");
               Ada.Integer_Text_IO.Put (Zaehler + 2, 1);
               Ada.Text_IO.New_Line;
            end if;
         end if;
      end loop;
   end Paare_Ausgeben;

begin
   Ada.Text_IO.Put ("Obere Grenze eingeben (positive Zahl): ");
   Ada.Integer_Text_IO.Get (Eingabe);
   Ada.Text_IO.Put_Line ("Primzahlpaare: ");
   Paare_Ausgeben (Eingabe);
end Primzahlpaare;
__________________
The only true thing about religion is
that it's false.
Chris_XY ist offline   Mit Zitat antworten
Alt 14.01.10, 19:36   #26 (permalink)
 
Registriert seit: 09.02.06
goflo Leistung: Facit NTK
Likes: 0
Standard

Es sind ja Lösungen in fast allen Sprachen vorhanden, aber eine VBA Lösung hab ich nicht gesehen.

Code:
Option Explicit

Sub PrimePairGenerator()
    Dim start As Integer, ende  As Integer
    Dim i As Integer, row As Integer
    
    start = Sheets("Tabelle1").Range("E1")
    ende = Sheets("Tabelle1").Range("E2")
    row = 1
    
    Columns("A:B").ClearContents
    
    If start <= 2 Then start = 3
    
    For i = start To ende Step 2
        If isPrime(i) = True And isPrime(i + 2) = True Then
            Sheets("Tabelle1").Cells(row, 1) = i
            Sheets("Tabelle1").Cells(row, 2) = i + 2
            row = row + 1
        End If
    Next i
    
End Sub

Function isPrime(nb As Integer) As Boolean
    Dim i As Integer
    
    If nb Mod 2 = 0 Then
        isPrime = False
        Exit Function
    End If
    
    For i = 3 To (nb/2) Step 2
        If nb Mod i = 0 Then
            isPrime = False
            Exit Function
        End If
    Next i
    
    isPrime = True
End Function
Angehängte Dateien
Dateityp: zip PrimePairs.zip (9,9 KB, 0x aufgerufen)

Geändert von goflo (15.01.10 um 17:02 Uhr)
goflo ist offline   Mit Zitat antworten
Alt 28.02.10, 18:22   #27 (permalink)
 
Benutzerbild von pytohn
 
Registriert seit: 28.03.09
pytohn Leistung: Facit NTK
Likes: 0
Standard Perl

Fange gerade an, Perl zu lernen, also hier in Perl:

Code:
print "Anfangswert:\t";
$start = <STDIN>;
print "Endwert:\t";
$ende = <STDIN>;

foreach $x ($start..$ende-2) {
        if (ist_primzahl($x) and ist_primzahl($x+2)) {
                print $x, "\t", $x+2, "\n";
        }
}

sub ist_primzahl {
        my($zahl) = @_;
        if ($zahl eq 1) {
                $prim = 0;
        }
        else {
                $prim = 1;
        }
        foreach $teiler (2..sqrt ($zahl)) {     # nur bis zur Wurzel von $zahl
                if ( ($zahl % $teiler) eq 0) {   # Modulo-Test
                        $prim = 0;      # Keine Primzahl: => falsch
                }
        }
        if ($prim eq 1) {
                return 1;       # Ist eine Primzahl: => wahr
        }
        else {
                return 0;       # Ist keine Primzahl:=> falsch
        }
}
pytohn ist offline   Mit Zitat antworten
Alt 02.04.10, 13:07   #28 (permalink)
 
Benutzerbild von pytohn
 
Registriert seit: 28.03.09
pytohn Leistung: Facit NTK
Likes: 0
Standard Perl verbessert

Habe meine alte Perlversion ein bisschen aufgewertet:

Code:
print "Anfangswert:\t";
$start = <STDIN>;
print "Endwert:\t";
$ende = <STDIN>;

foreach $x ($start..$ende-2) {
        if (ist_primzahl($x) and ist_primzahl($x+2)) {
                print $x, "\t", $x+2, "\n";
        }
}

sub ist_primzahl {
        my($zahl) = @_;
        if ($zahl eq 1) {
                return 0;
        }
        foreach $teiler (2..sqrt ($zahl)) {     # nur bis zur Wurzel von $zahl
                if ( ($zahl % $teiler) eq 0) {  # Modulo-Test
                        return 0;       # Keine Primzahl: => falsch
                }
        }
        return 1;
}
pytohn ist offline   Mit Zitat antworten
Alt 23.12.10, 15:13   #29 (permalink)
 
Registriert seit: 10.11.10
DMRMcK Leistung: Z3
Likes: 0
Standard

Eine Möglichkeit in VB.

VB-Code   
Code:
Module Module1
    Public anfZahl As Integer
    Public endZahl As Integer
    Public zahlen(0) As Integer
    Public zaehler As Integer = 0

    Sub Main()
        Console.Write("Bitte den Anfangswert des Wertebereichs eingeben: ")
        anfZahl = Console.ReadLine
        Console.Write("Bitte den Endwert des Wertebereichs eingeben: ")
        endZahl = Console.ReadLine
        Console.WriteLine()

        Dim prim(endZahl + 1) As Boolean
        For i As Integer = 0 To endZahl + 1
            prim(i) = True
        Next
        For j As Integer = 2 To endZahl
            prim(j) = False
        Next

        primSuche(prim)

        For z As Integer = 0 To zahlen.Length - 2
            If zahlen(z) + 2 = zahlen(z + 1) Then
                Console.WriteLine(zahlen(z) & " - " & zahlen(z + 1))
            End If
        Next

        Console.ReadLine()
    End Sub

    Public Sub primSuche(ByRef prim() As Boolean)
        For i As Integer = 2 To endZahl
            If Not prim(i) Then
                ReDim Preserve zahlen(zaehler)
                zahlen(zaehler) = i
                zaehler += 1
                For j As Integer = i * i To endZahl Step i
                    prim(j) = True
                Next
            End If
        Next
    End Sub

End Module
DMRMcK ist offline   Mit Zitat antworten
Alt 08.06.11, 09:04   #30 (permalink)
 
Registriert seit: 07.06.11
NattleBet Leistung: Facit NTK
Likes: 0
Standard

JAVA   
public class Primzahlenpaar {
private boolean isPrim(int number) {
if (number <= 1) return false;
for (int i = 2; i < number; i++) if (number % i == 0) return false;
return true;
}

private void next(int i) {
if (isPrim(i)) if (isPrim(i + 2)) System.out.println(i + " - " + (i + 2));
}

public static void main(String[] args) {
int endwert = 30;
Primzahlenpaar prim = new Primzahlenpaar();
for (int i = 1; i <= endwert - 2; i++) prim.next(i);
}
}

Geändert von NattleBet (08.06.11 um 09:06 Uhr)
NattleBet ist offline   Mit Zitat antworten
Antwort
   

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Programmieraufgaben » Aufgabe Nr. 1: Primzahlenpaare
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Mathe Aufgabe Nimda05 Science & Fiction 10 26.08.08 11:58
UNI Aufgabe Kaya Code Kitchen 19 05.04.07 19:16
Aufgabe daddycool Code Kitchen 5 13.01.06 08:28
Aufgabe poldi Code Kitchen 2 14.01.04 18:02


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61