Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[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.

Wieviele Steine passen in eine Fläche?

Diskussion: Wieviele Steine passen in eine Fläche? im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Anzeige Also, Jungs (bis auf mauralix und lightsaver): Ihr macht Euch die Aufgabe zu einfach. Auch wenn es nur um ...

Antwort
Alt 16.12.07, 02:36   #16 (permalink)
 
Registriert seit: 17.02.06
Harry Boeck Leistung: Facit NTK
Likes: 0
Standard

Anzeige

Also, Jungs (bis auf mauralix und lightsaver):

Ihr macht Euch die Aufgabe zu einfach.
Auch wenn es nur um rechteckige Bausteine geht und auch wenn diese alle gleich aussehen, ist das Problem ein Optimierungsproblem.

Ihr könnte mit der einfachen Flächendivision einen Grenzwert bestimmen, der eventuell erreicht werden KANN.

Sofern die beiden Bedingungen "rechteckig" und "alle gleich" nicht auf die Bausteine und die auszulegende Fläche zutreffen, wird auf jeden Fall eine Aufgabe daraus, die exponentiellen Lösungsaufwand erfordert und bei der noch nicht mal feststeht, daß die Bausteine horizontal oder vertikal ausgerichtet eine optimale Flächendeckung ergeben.

MIT diesen beiden Bedingungen müßte man jedoch auch erstmal beweisen, daß die Flächennutzung bei horizontaler und vertikaler Ausrichtung optimal werden muß. Erst dann lohnt es sich, einen Algorithmus dafür zu schreiben.

Mal als Beispiel:

Baustein 3*5
Fläche 13*14

Grenzwert nach Flächendivision: 12, Rest 2
tatsächlich mögliche Auslastung: 11,
aber nur, wenn die Bausteine etwa (vom Prinzip her) SO angeordnet werden:

Code:
1111122222bbb
1111122222bbb
1111122222bbb
3333344444bbb
3333344444bbb
3333344444
5555566666
5555566666
5555566666
777888999aaa 
777888999aaa
777888999aaa
777888999aaa
777888999aaa
geht man geringfügig anders ran, kann man eventuell nur noch 10 unterbringen.
GANZ so trivial ist die Aufgabe also nicht...

Falls die Annahme zutrifft, daß Optimalität erreiche werden kann, wenn man die Fläche damit auszulegen beginnt, daß man Bausteine einfach nur in einer Richtung ausgerichtet und in einer Ecke angesetzt erstmal bis auf die Reststreifen verteilt und dann jene zu füllen versucht, indem man die Bausteine 90° gedreht und wieder in einer verbleibenden Ecke angesetzt verteilt, müßt Ihr immer noch mindestens zwei Varianten davon probieren und die bessere auswählen!

Oder mit irgendwelchen Teilerverhältnis-Betrachtungen vorneweg die Optimallösung voraussagen.
Harry Boeck ist offline   Mit Zitat antworten
Alt 16.12.07, 04:04   #17 (permalink)
ba2
Guest
 
Likes:
Standard

Ich hab da mal was in Python gebastelt, um den Code klein zu halten vertraue ich mal darauf das die Eingaben Zaheln sind

Code:
#Autor :   BA2
#Link  :   http://www.abba-skript.de?seite=steine(Python)

#Flaeche festlegen
print 'Die Flaeche des Feldes wird in Millimeter eingegeben.\nEs sind nur ganze Zahlen erlaubt.'
feld_breite = input('Die Breite des Feldes in mm? ')
feld_laenge = input('Die Laenge des Feldes in mm? ')
feld_flaeche = feld_breite * feld_laenge
#bestimmen wieviele Stellen die Zahl hat
feld_zeichen = len(list(str(feld_flaeche))) + 4

#Steingroesse festlegen
print '\nDie Flaeche des Steines wird in Millimeter eingegeben.\nEs sind nur ganze Zahlen erlaubt.'
stein_breite = input('Die Breite des Steines in mm? ')
stein_laenge = input('Die Laenge des Steines in mm? ')
stein_flaeche = stein_breite * stein_laenge
#bestimmen wieviele Stellen die Zahl hat
stein_zeichen = len(list(str(stein_flaeche))) + 4

#Rechnungen
steine_insgesamt = feld_flaeche / stein_flaeche
steine_insgesamt_zeichen = len(list(str(steine_insgesamt))) + 7

#Gegebenheiten Ausgeben
print '\nGegeben:\n'
#Feld
print 'Feld Breite   = ',feld_breite,'mm'
print 'Feld Laenge   = ',feld_laenge,'mm'
#Stein
print 'Stein Breite  = ',stein_breite,'mm'
print 'Stein Laenge  = ',stein_laenge,'mm\n'

#Rechnung Ausgeben
print '\nRechnungen:\n'
#Rechnung Feld Flaeche
print 'Feld Flaeche = Feld Breite * Feld Laenge'
print 'Feld Flaeche =',feld_breite,'mm','*',feld_laenge,'mm'
print 'Feld Flaeche =',feld_flaeche,'mm2'
print ' '*14, '-'*feld_zeichen,'\n'

#Rechnung Stein Flaeche
print 'Stein Flaeche = Stein Breite * Stein Laenge'
print 'Stein Flaeche =',stein_breite,'mm','*',stein_laenge,'mm'
print 'Stein Flaeche =',stein_flaeche,'mm2'
print ' '*15, '-'*stein_zeichen,'\n'

#Rechnung wie viele Steine im Feld im Optimal fall passen
print 'Steine Insgesamt = Feld Flaeche / Stein Flaeche'
print 'Steine Insgesamt =',feld_flaeche,'mm2','/',stein_flaeche,'mm2'
print 'Steine Insgesamt =',steine_insgesamt,'Steine'
print ' '*18, '='*steine_insgesamt_zeichen,'\n'
mfg ba2
  Mit Zitat antworten
Alt 16.12.07, 09:06   #18 (permalink)
 
Benutzerbild von ChiefWiggum
 
Registriert seit: 09.10.07
ChiefWiggum Leistung: 8086
ChiefWiggum eine Nachricht über ICQ schicken
Likes: 11
Standard

Hmm also wie ich das verstanden hab, soll man die Steine auch drehen,
um die optimale Fläche zu erhalten.

z.B:

Fläche 5x3
Stein: 2x2
Dann nicht nur einfach
[XX_]
[XX_]
[XX_]
[XX_]
[XX_]
(X= steinfeld, _=leer)
sondern
[XXO]
[XXO]
[XXO]
[XXO]
[XX_]
(O= gedrehter Stein)

Oder hab ich das nicht gecheckt?


Cya
__________________
Be the source always with you.
ChiefWiggum ist offline   Mit Zitat antworten
Alt 16.12.07, 11:06   #19 (permalink)
JTron
Guest
 
Likes:
Standard

Zitat:
Original von 0wnZ
schmeißt nur errors aus :o
Sorry, mehr Infos
Also: Unter WinXP mit Konsole sagt es, dass bei "Passt nicht" in den Zeilen 12, 14, 16, 18, 28 ein kEND erwartet wird anstelle von tCONSTANT
und in Zeile 35 wird ein $end anstelle eines kEND erwartet.
Ich hab den Code 1 zu 1 in Scite übernommen und einfach gesichert.

edit2: Ich sehs, da fehlen 2 "n"s nach dem \ für den Zeilenumbruch in den Zeilen 5 und 9 ! Damit wird das Anführungszeichen escaped und der String nicht beendet !
Ja stimmt, ich hatte es schon bemerkt, dachte aber dass ich es schon richtig gepostet hätte

Ist verbessert
  Mit Zitat antworten
Alt 16.12.07, 17:16   #20 (permalink)
 
Registriert seit: 17.02.06
Harry Boeck Leistung: Facit NTK
Likes: 0
Standard

Hmmm, vielleicht solltet Ihr Euch erstmal untereinander klar werden, was Ihr überhaupt wollt? Bzw. was ihr meint?

Wenn Ihr von Problemen in 3 Dimensionen redet, solltet Ihr Euch ALLE darauf festlegen.
Wenn Ihr in zwei oder gar nur in einer Dimension denken wollt, natürlich dasselbe.
Sonst verhalten sich Eure Postings wie Socken zu Wackelpudding.

Ich vermute mal, daß das ursprünglich genannte Problem mitnichten darin besteht, zu beweisen, daß man simple Input- und Print-Operationen und Grundrechenarten in irgendeiner Programmiersprache beherrscht.

Aber vielleicht sagt der Aufgabensteller nochmal ein Wort dazu?

----

Ein paar weitere Gedanken:

Schon ein triviales Einstiegs-Beispiel zeigt, daß die Überlegungen zu Vereinfachungen allesamt Murks sind:

Man nehme längliche Bausteine 1*n und einen Kasten mit einer Seitenlänge von (n-1) * (2n-1). Senkrecht paßt nichts. Waagerecht paßt genau eine Reihe von n-1 Bausteinen, die aber ein riesiges Loch von (n-1)*(n-1) ungefüllt läßt. Dieses kann jedoch noch mit einer Menge von schräg liegenden Bausteinen gefüllt werden. Und eventuell wird der verbleibende Restplatz dadurch verringert, daß man sämtliche Bausteine von vornherein (und dann weniger schräg) einsetzt.

Nachdem ich jetzt zu dieser Erkenntnis gekommen bin, daß schräge Plazierung - falls sie vom Aufgabensteller nicht explizit ausgenommen wird - notwendig sein kann, halte ich die Aufgabe für überhaupt alles andere als trivial. Ideen zur bedingungslos und garantiert optimalen Lösung fehlen mir jedenfalls zur Zeit noch.
Harry Boeck ist offline   Mit Zitat antworten
Alt 01.02.09, 16:24   #21 (permalink)
 
Registriert seit: 22.03.08
MontyPerl Leistung: Facit NTK
Likes: 0
Standard

Ich hab mich mal drangesetzt.

Als Optimierungen ist folgende Prämisse eingeflossen:
Optimale Platzausnutzung kann (nur) erreicht werden, wenn die Steine zusammenhängend platziert werden (also keine "freistehenden" Steine existieren).

Der Algorithmus ist aber immernoch ziemlich langsam (Er schafft das 13x14 Feld mit 3x5 Bausteinen Beispiel unter einer Minute. Vor der Optimierung lief der stundenlang fröhlich vor sich hin...). Das "Urbeispiel" (200x250 Feld mit 15x10 Bausteinen) würde wahrscheinlich seeeeeehr lange laufen.... Ohne weitere intelligente Optimierungen ist der Algo einfach zu langsam für solche Dimensionen.. (@weitere Optimierungen: Sowas wie beim Damenproblem beispielsweise. Das Hauptproblem in immer kleinere Teilprobleme zerteilen und am Ende wieder alles zusammenführen. Oder eine Art von caching ausarbeiten. Aber das war mir jetzt zu "fancy" ;) Bin froh das es überhaupt funktioniert.)

Ich komm insgesamt auf 451 Zeilen Code (stdlib.h und stdio.h nicht mitgezählt).
Naja, dafür hab ich on-the-way auch noch das maximal-rectangle-problem gelöst (getBiggestFree()), ohne das es direkt was mit der Aufgabenstellung zu tun hätte. (Wird auch nicht im Algorithmus verwendet.)


rect.c   
Erstmal das Hauptprogramm, beziehungsweise das userinterface, rect.c:
Code:
#include <stdio.h>
#include <stdlib.h>
#include "rect.h"

/*
 * Es soll ein Algorithmus entwickelt werden der die maximale Anzahl an
 * Bausteinen bestimmt die in eine bestimmte Fläche passen.
 *
 * z.B: ich gebe "ihm" eine Fläche von 2m x 2,5m vor und sage das ein Baustein 0,15m x 0.1m groß ist.
 * Nun soll der Algorithmus die Bausteine so anordnen das die Große Fläche möglichst vollständig
 * abgedeckt wird. und es so wenig wie möglich Lücken bleiben.
 *
 * Die anzahl de genutzten Bausteine und wenn möglich die Form in der die
 * Bausteine verlegt worden sind, sollen ausgegeben werden. 
 */

int main(int argc, char *argv[]) {
    if (argc != 5) {
        fprintf(stderr, "usage: %s <fieldxdim> <fieldydim> <rectxdim> <rectydim>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    int xdim, ydim;
    xdim = atoi(argv[1]);
    ydim = atoi(argv[2]);
    field *f = createField(xdim, ydim);

    int rectxsize, rectysize;
    rectxsize = atoi(argv[3]);
    rectysize = atoi(argv[4]);
    rect *r = createRect(0, 0, rectxsize, rectysize);
    fillField(f, r);
    return EXIT_SUCCESS;
}
Dann die eigentliche Implementierung:
rect.h   
Code:
#include <stdio.h>
#include <stdlib.h>
#ifndef XALLOC_H
    #include "xalloc.h"
#endif
#include "voidStack.h"

typedef struct {
    int x1, y1, x2, y2;     /* with x2 > x1 and y2 > y1 */
} rect;

typedef struct {
    int **f;
    rect *r;        /* the rect describing the field */
    int xdim, ydim; /* redundant, since those infos are already contained within
                       the supplied rect, but it's easier to read that way.. */
} field;

void printField(field *f);

field *createField(int xdim, int ydim);
void delField(field *f);
void setField(field *f, rect *r, int val);
void copyField(field *src, field *dest);
int isFree(field *f, rect *r);      /* returns 1 if the area described by rect is all zeros in field */
int getFreeCount(field *f);
rect *getBiggestFree(field *f);     /* gets biggest free rect in field *f */
stack getAllFree(field *f, rect *r);
void fillField(field *f, rect *r);
int fillFieldRec(field *f, rect *r, int rectcount, int *max, field *sol);

rect *createRect(int startx, int starty, int xsize, int ysize);
void copyRect(rect *src, rect *dest);
void setRect(rect *r, int x1, int y1, int x2, int y2);
int getArea(rect *r);
void delRect(rect *r);
void moveRect(rect *r, int x, int y);
void resizeRect(rect *r, int xsize, int ysize);
void rotateRect(rect *r);           /* rotates *r by 90 degrees. (the top left corner will be the same) */
int isInRect(rect *r, int x, int y);
int isSubRect(rect *r, rect *sub);
int areCongruent(rect *r, rect *s);



void fillField(field *f, rect *r) {
    int max = 0;
    field *solution = createField(f->xdim, f->ydim);
    fillFieldRec(f, r, 1, &max, solution);
    printField(solution);
}

int fillFieldRec(field *f, rect *r, int rectcount, int *max, field *sol) {
    stack p = getAllFree(f, r);
    rect *new = shift(p);
    if (new == NULL) {
        destroyStack(p);
        if (rectcount > *max) {
            *max = rectcount;
            copyField(f, sol);
            if (getFreeCount(f) < getArea(r)) {
                return 1;
            }
            printField(f);  /* print intermediate solutions */
        }
        return 0;
    }
    while (new != NULL) {
        setField(f, new, rectcount);
        if (fillFieldRec(f, r, rectcount + 1, max, sol)) {
            return 1;
        }
        setField(f, new, 0);
        delRect(new);
        new = shift(p);
    }
    destroyStack(p);
    return 0;
}

rect *createRect(int startx, int starty, int xsize, int ysize) {
    rect *r = xmalloc(sizeof(rect));
    r->x1 = startx;
    r->y1 = starty;
    r->x2 = startx + xsize - 1;
    r->y2 = startx + ysize - 1;
    return r;
}

void delRect(rect *r) {
    free(r);
}

void setRect(rect *r, int x1, int y1, int x2, int y2) {
    r->x1 = x1;
    r->y1 = y1;
    r->x2 = x2;
    r->y2 = y2;
}

void copyRect(rect *src, rect *dest) {
    /* sets *dest to describe the same area as *src */
    dest->x1 = src->x1;
    dest->y1 = src->y1;
    dest->x2 = src->x2;
    dest->y2 = src->y2;
}

int getArea(rect *r) {
    return ( ((r->x2 - r->x1) + 1) * ((r->y2 - r->y1) + 1) );
}

void resizeRect(rect *r, int xsize, int ysize) {
    r->x2 = r->x1 + xsize;
    r->y2 = r->y1 + ysize;
}

void moveRect(rect *r, int x, int y) {
    int xsize, ysize;
    xsize = r->x2 - r->x1;
    ysize = r->y2 - r->y1;
    r->x1 = x;
    r->y1 = y;
    resizeRect(r, xsize, ysize);
}

void rotateRect(rect *r) {
    /* rotates *r by 90 degrees. (the top left corner will stay the same) */
    int xsize, ysize;
    xsize = r->x2 - r->x1;
    ysize = r->y2 - r->y1;
    resizeRect(r, ysize, xsize);
}

field *createField(int xdim, int ydim) {
    int *rows = xmalloc(xdim * ydim * sizeof(int));
    int **cols = xmalloc(ydim * sizeof(int *));
    int i;
    for (i = 0; i < ydim; i++) {
        cols[i] = &rows[i * xdim];
    }
    rect *r = xmalloc(sizeof(rect));
    r->x1 = 0;
    r->y1 = 0;
    r->x2 = xdim - 1;
    r->y2 = ydim - 1;
    field *f = xmalloc(sizeof(field));
    f->f = cols;
    f->r = r;
    f->xdim = xdim;
    f->ydim = ydim;
    setField(f, f->r, 0);
    return f;
}

void delField(field *f) {
    free(f->r);
    int i;
    for (i = 0; i < f->ydim; i++) {
        free(f->f[i]);
    }
    free(f->f);
    free(f);
}

void setField(field *f, rect *r, int val) {
    if (! isSubRect(f->r, r)) {
        return;
    }
    int x, y;
    for (y = r->y1; y <= r->y2; y++) {
        for (x = r->x1; x <= r->x2; x++) {
            f->f[y][x] = val;
        }
    }
}

void copyField(field *src, field *dest) {
    int x, y;
    for (y = 0; (y < src->ydim && y < dest->ydim); y++) {
        for (x = 0; (x < src->xdim && x < dest->xdim); x++) {
            dest->f[y][x] = src->f[y][x];
        }
    }
}

int isFree(field *f, rect *r) {
    /* returns true if the area described by *r is all zeros in *f */
    if (! isSubRect(f->r, r)) {
        return 0;
    }
    int x, y;
    for (y = r->y1; y <= r->y2; y++) {
        for (x = r->x1; x <= r->x2; x++) {
            if (f->f[y][x]) {
                /* nonzero */
                return 0;
            }
        }
    }
    return 1;
}

int getFreeCount(field *f) {
    int x, y, count = 0;
    for (y = 0; y < f->ydim; y++) {
        for (x = 0; x < f->xdim; x++) {
            if (f->f[y][x] == 0) {
                count++;
            }
        }
    }
    return count;
}

rect *getBiggestFree(field *f) {
    int x1, y1, x2, y2, size, maxsize;
    rect *tmp = createRect(0, 0, 1, 1);
    rect *max = createRect(0, 0, 1, 1);
    maxsize = 0;
    for (x1 = 0; x1 < f->xdim; x1++) {
    for (y1 = 0; y1 < f->ydim; y1++) {
    for (x2 = x1; x2 < f->xdim; x2++) {
    for (y2 = y1; y2 < f->ydim; y2++) {
        setRect(tmp, x1, y1, x2, y2);
        size = getArea(tmp);
        if (size > maxsize && isFree(f, tmp)) {
            maxsize = size;
            copyRect(tmp, max);    /* max now describes the same rect as tmp */
        }
    }
    }
    }
    }
    delRect(tmp);
    if (getArea(max) == 1) {
        delRect(max);
        return NULL;
    }
    return max;
}

stack getAllFree(field *f, rect *r) {
    /* gets free areas within *f where *r fits (actually not all, see optimization below) */
    int x1, y1, x2, y2;
    stack s = newStack(2);
    rect *tmp = createRect(0, 0, 1, 1);
    int xmin, ymin;
    xmin = r->x2 - r->x1;
    ymin = r->y2 - r->y1;
    for (x1 = 0; x1 < f->xdim; x1++) {
    for (y1 = 0; y1 < f->ydim; y1++) {
    for (x2 = x1; x2 < f->xdim; x2++) {
    for (y2 = y1; y2 < f->ydim; y2++) {
        if (         
            ((x1 == 0) || f->f[y1][x1-1])   /* only allow "continuous" placement */
         && ((y1 == 0) || f->f[y1-1][x1])
        ) { 
            setRect(tmp, x1, y1, x2, y2);
            if (areCongruent(tmp, r) && isFree(f, tmp)) {
                push(s, tmp);
                tmp = createRect(0, 0, 1, 1); 
            }   
        }   
    }   
    }   
    }
    }
    push(s, NULL);
    return s;
}

void printField(field *f) {
    int x, y;
    for (y = 0; y < f->ydim; y++) {
        for (x = 0; x < f->xdim; x++) {
            printf("%c ", f->f[y][x] ? f->f[y][x] + 64 : '.');
        }
        printf("\n");
    }
    printf("-- \n");
}

int isInRect(rect *r, int x, int y) {
    if (x >= r->x1 && x <= r->x2 && y >= r->y1 && y <= r->y2) {
        return 1;
    }
    return 0;
}

int isSubRect(rect *r, rect *sub) {
    if (isInRect(r, sub->x1, sub->y1) && isInRect(r, sub->x2, sub->y2)) {
        return 1;
    }
    return 0;
}

int areCongruent(rect *r, rect *s) {
    int rxsize, rysize, sxsize, sysize, success = 0;
    rxsize = r->x2 - r->x1;
    rysize = r->y2 - r->y1;
    sxsize = s->x2 - s->x1;
    sysize = s->y2 - s->y1;
    if (
        (rxsize == sxsize && rysize == sysize)
     || (rxsize == sysize && rysize == sxsize)
    ) {
        success = 1;
    }
    return success;
}


Der Header für den "typenlosen" void pointer Stack:
voidStack.h   
Code:
#include <stdio.h>
#include <stdlib.h>
#ifndef XALLOC_H
    #include "xalloc.h"
#endif

#define POP_EMPTY NULL

typedef struct stackStruct {
    void **ptr;
    int pos;
    int size;
} *stack;

stack newStack(int size);
void destroyStackDeep(stack s);
void destroyStack(stack s);
void push(stack s, void *ptr);
void *pop(stack s);
void *top(stack s);
void *shift(stack s);

stack newStack(int size) {
    stack stck = xmalloc(sizeof(struct stackStruct));
    void **ptr = xmalloc(size * sizeof(void *));
    stck->ptr = ptr;
    stck->pos = 0;
    stck->size = size;
    return stck;
}

void destroyStack(stack s) {
    free(s->ptr);
    free(s);
}

void destroyStackDeep(stack s) {
    void *ptr = pop(s);
    while (ptr != NULL) {
        free(ptr);  /* make sure the ptrs in the stack are actually free()able if you call this method */
        ptr = pop(s);
    }
    destroyStack(s);
}


void push(stack s, void *ptr) {
    if (s->pos == s->size - 1) {
        s->size *= 2;
        s->ptr = xrealloc(s->ptr, s->size * sizeof(void *));
    }
    s->ptr[s->pos] = ptr;
    s->pos++;
}

void *pop(stack s) {
    if (s->pos == 0) {
      return POP_EMPTY;
    }
    s->pos--;
    return s->ptr[s->pos+1];
}

void *top(stack s) {
    return s->ptr[s->pos];
}

void *shift(stack s) {
    void *retptr = s->ptr[0];
    int i;
    for (i = 1; i < s->size; i++) {
        s->ptr[i-1] = s->ptr[i];
    }
    return retptr;
}


Und zu guter letzt für die *alloc() Familie mit automatischem Errorchecking:
xalloc.h   
Code:
#include <stdlib.h>
#include <stdio.h>

#define XALLOC_H 1

void *xmalloc(int size) {
    void *ptr = malloc(size);
    if (ptr == NULL) {
        fprintf(stderr, "not enough memory\n");
        exit(EXIT_FAILURE);
    }
    return ptr;
}

void *xcalloc(int nitems, int size) {
    void *ptr = calloc(nitems, size);
    if (ptr == NULL) {
        fprintf(stderr, "not enough memory\n");
        exit(EXIT_FAILURE);
    }
    return ptr;
}

void *xrealloc(void *ptr, int size) {
    ptr = realloc(ptr, size);
    if (ptr == NULL) {
        fprintf(stderr, "not enough memory\n");
        exit(EXIT_FAILURE);
    }
    return ptr;
}


Test:
Code:
$ time ./rect 13 14 3 5
A A A D D D G G G I I I . 
A A A D D D G G G I I I . 
A A A D D D G G G I I I . 
A A A D D D G G G I I I . 
A A A D D D G G G I I I . 
B B B E E E H H H J J J . 
B B B E E E H H H J J J . 
B B B E E E H H H J J J . 
B B B E E E H H H J J J . 
B B B E E E H H H J J J . 
C C C C C F F F F F . . . 
C C C C C F F F F F . . . 
C C C C C F F F F F . . . 
. . . . . . . . . . . . . 
-- 
A A A C C C C C H H H H H 
A A A C C C C C H H H H H 
A A A C C C C C H H H H H 
A A A D D D D D I I I I I 
A A A D D D D D I I I I I 
B B B D D D D D I I I I I 
B B B E E E E E J J J J J 
B B B E E E E E J J J J J 
B B B E E E E E J J J J J 
B B B F F F G G G K K K . 
. . . F F F G G G K K K . 
. . . F F F G G G K K K . 
. . . F F F G G G K K K . 
. . . F F F G G G K K K . 
-- 
A A A C C C C C H H H H H 
A A A C C C C C H H H H H 
A A A C C C C C H H H H H 
A A A D D D D D I I I I I 
A A A D D D D D I I I I I 
B B B D D D D D I I I I I 
B B B E E E E E J J J J J 
B B B E E E E E J J J J J 
B B B E E E E E J J J J J 
B B B F F F G G G K K K . 
. . . F F F G G G K K K . 
. . . F F F G G G K K K . 
. . . F F F G G G K K K . 
. . . F F F G G G K K K . 
-- 

real    0m47.021s
user    0m44.408s
sys     0m0.008s
Da er Zwischenlösungen ausgibt wird die Lösung bereits wenige Millisekunden nach dem Start ausgegeben, allerdings braucht er dann noch ne Weile um festzustellen, ob das wirklich die Beste Lösung ist.. (Btw kann man (wenn man denn will) am Anfang der fillFieldRec() Funktion einfach ein printField(f); hinpacken und sich die Ausgabe dann animiert mittles desselben Perl-Skripts vom Springerproblemthread ausgeben lassen.)
MontyPerl ist offline   Mit Zitat antworten
Alt 24.02.09, 22:00   #22 (permalink)
 
Registriert seit: 09.02.06
goflo Leistung: Facit NTK
Likes: 0
Standard

ja, mir war langweilig...

meine Java Lösung:   

Code:
package de.hackerboard.programmieraufgaben.steine_in_feld;

public class StoneCalculator {
	public static void main(String[] args) {
		System.out.println("es passen " + calcualte(20, 20, 6, 1) + " Steine ins Feld...");
		System.out.println("es passen " + calcualte(20, 20, 6, 2) + " Steine ins Feld...");
		System.out.println("es passen " + calcualte(10, 20, 12, 1) + " Steine ins Feld...");
		System.out.println("es passen " + calcualte(8, 20, 12, 10) + " Steine ins Feld...");
	}
	
	public static int calcualte(double fieldWidth, double fieldLength,
								double stoneWidth, double stoneLength) {
		int rows = 0;
		int cols = 0;
		int rotatedStones = 0;
		double r = 0.0;
		
		if ((stoneWidth > fieldWidth) || (stoneLength > fieldLength)) {
			double temp = stoneWidth;
			stoneWidth = stoneLength;
			stoneLength = temp;
		}
		
		cols = (int)(fieldWidth / stoneWidth);
		r = fieldWidth % stoneWidth;
		if ((stoneLength <= r) && (stoneWidth <= fieldLength)) {
			rotatedStones = calcualte(r, fieldLength, stoneLength, stoneWidth);
		}
		
		rows = (int)(fieldLength / stoneLength);
		r = fieldLength % stoneLength;
		if ((stoneWidth <= r) && (stoneLength <= fieldWidth)) {
			rotatedStones += calcualte(fieldLength, r, stoneWidth, stoneLength);
		}
		
		return cols*rows + rotatedStones;
	}
}


Wie von 'AlterHacker' angemerkt werden Steine auch gedreht wenn Sie denn in die übrig bleibende Fläche passen.

//EDIT: da ich dabei bin mich mit Python/Jython anzufreunden auch noch eine passende Lösung dazu. Algorithmus ist der selbe!
meine Python/Jython Lösung:   

Code:
if __name__ == '__main__':
    from SteineInFeld import calcStones
    
    print 'Feld: 20x20  -  Stein: 6x1    --> %i' % (calcStones(20,20,6,1))
    print 'Feld: 20x20  -  Stein: 6x2    --> %i' % (calcStones(20,20,6,2))
    print 'Feld: 10x20  -  Stein: 12x1   --> %i' % (calcStones(10,20,12,1))
    print 'Feld: 8x20   -  Stein: 12x10  --> %i' % (calcStones(8,20,12,10))
Code:
def calcStones(fieldW, fieldL, stoneW, stoneL):
    if ((stoneW > fieldW) or (stoneL > fieldL)):
        temp = stoneW
        stoneW = stoneL
        stoneL = temp
        
    rotatedStones = 0
    cols = (int)(fieldW / stoneW)
    r = fieldW % stoneW
    if ((stoneL <= r) and (stoneW <= fieldL)):
        rotatedStones = calcStones(r, fieldL, stoneL, stoneW)

    
    rows = (int)(fieldL / stoneL)
    r = fieldL % stoneL
    if ((stoneW <= r) and (stoneL <= fieldW)):
        rotatedStones += calcStones(fieldL, r, stoneW, stoneL)
    
    return cols * rows + rotatedStones
goflo ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Programmieraufgaben » Wieviele Steine passen in eine Fläche?
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
5cm weiser Fläche sprudelgehirn (Web-) Design und webbasierte Sprachen 3 06.10.09 16:03
Wieviele Forumsmitglieder braucht man, um eine Glühbirne zu wechseln? ivegotmail Fun Section 22 16.09.07 21:14
Wieviele Telefonnummern q9fx7 Internet Allgemein 2 13.09.07 19:18
Wieviele Firmen haben eine Sicherheitspolitik? saftig (In)security allgemein 1 05.03.06 18:19
[JAVA] Tetris - Rotation der Steine Boar Code Kitchen 13 20.06.05 20:49


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