Προγραματιστική Πρόκληση Νο 0: Χριστουγενιάτικα δέντρα

Πέρυσι είχαμε κάνει ένα “διαγωνισμό” στο Telegram, και ζητάγαμε να φτιαχτεί ένα πρόγραμμα που να φτιάχνει χριστουγεννιάτικα δέντρα. Μπορεί να είναι ένα πρόγραμμα που τυπώνει απλά το παρακάτω με print, ή να φτιάχνει κάτι σαν το παρακάτω

Ακόμα με με απλές εντολές echo σε Bash, η λύση είναι δεκτή (και η ικανοποίηση που θα το καταφέρεις μεγάλη), οπότε περιμένουμε τις λύσεις σας

            ||            
           *||*           
          **||**          
         ***||***         
        ****||****        
       *****||*****       
      ******||******      
     *******||*******     
    ********||********    
   *********||*********   
  **********||**********  
 ***********||*********** 
            ||            

Και ξεκινάω με την λύση που είχα δώσει πέρυσι, μόνο μην μου τρομάξετε :stuck_out_tongue:

#include <algorithm>
#include <cassert>
#include <string>
#include <vector>
#include <iostream>
#include <iterator>

using namespace std;

int main() {
    constexpr size_t n = 12;
    constexpr auto fill_char = ' ';
    constexpr auto star_char = '*';

    auto level = n;
    assert(level >= 1);

    auto base_str = string(level, star_char) + "||" + string(level, star_char);
    auto items = vector<string>(level, base_str);

    transform(items.begin(), items.end(), items.begin(), [&level](string &it) -> string {
        it.replace(it.begin(), it.begin() + level, level, fill_char);
        it.replace(it.end() - level, it.end(), level, fill_char);
        level--;
        return it;
    });

    // Print Tree
    copy(items.begin(), items.end(), ostream_iterator<string>(cout, "\n"));
    // Print the log "||" base
    cout << items.front() << "\n";

    return EXIT_SUCCESS;
}
1 «Μου αρέσει»

Σε Python:

print('''            ||            
           *||*           
          **||**          
         ***||***         
        ****||****        
       *****||*****       
      ******||******      
     *******||*******     
    ********||********    
   *********||*********   
  **********||**********  
 ***********||*********** 
            ||            ''')
5 «Μου αρέσει»

GW basic emulator σε Linux mint. (Μη γελάτε, ό,τι μπορεί ο καθένας).


Το δεντράκι “αναβοσβήνει” 100 φορές (σύμφωνα με το εύρος του LI στη γραμμή 10), επιλέγοντας τυχαία ανάμεσα σε “#” και “*”. Η DE στην 130 είναι απλό delay.

10 FOR LI=1 TO 100
20 CLS
30 PRINT STRING$(35,32)+“/"
40 PRINT STRING$(34,32)+”< >"
50 PRINT STRING$(35,32)+“/”
60 PRINT STRING$(35,32)+“||”
80 FOR X=1 TO 10
90 RANDOMIZE(X100): A=INT(10RND(1)):IF A/2=INT(A/2)THEN CH=42 ELSE CH=35
100 PRINT STRING$(35-X,32)+STRING$(X,CH)+“||”+STRING$(X,CH)
110 NEXT X
120 PRINT STRING$(25,32)+STRING$(10,““)+”||“+STRING$(10,””)
130 FOR DE=1 TO 20000:NEXT
140 NEXT LI

Thanks to @lucinos (* το extension .bas μπαίνει αυτόματα. Χωρίς το “,a” που μου συνέστησες όμως, ανοίγοντας το αρχείο με office writer, έβλεπα ιερογλυφικά).


PS: Κάτι κάνω λάθος και ο κώδικας δεν εμφανίζεται σωστά.

7 «Μου αρέσει»

Εγώ cLopy :stuck_out_tongue:

Ρίξτε αυτό στο Terminal :smiley:

wget -d -c -O "christmas.sh" "https://raw.githubusercontent.com/sergiolepore/ChristBASHTree/master/tree-EN.sh" && chmod +x christmas.sh && ./christmas.sh
3 «Μου αρέσει»

Πραγματικά εντυπωσιακό, αλλά είπαμε να το κάνεις μόνος σου :stuck_out_tongue:

Αλλά επί την ευκαιρία, έδωσες ένα πολύ καλό παράδειγμα του τι δεν πρέπει να κάνεις αν δεν θέλεις να χάσεις τον έλεγχο του υπολογιστή σου.

Κάποιος

  • που δεν ξέρεις σου ζητάει
  • Να γράψεις εντολές που ίσως δεν καταλαβαίνεις
  • Που κατεβάζουν και τρέχουν ένα προγραμμα
  • Που κάνει κάτι καθόλου σηματικο

Αλήθεια τι μπορεί να πάει στραβά ;

Αν κάποιος θέλει να δει τον κώδικα, που την συγκεκριμένη στιγμή που το βλέπω είναι ασφαλής και κάνει αυτό που υπόσχετε. Δεν μπορείς να ξέρεις όμως αν κάποιος τον αλλάξει αύριο

Για να μην παρεξηγηθώ, τα λέω αυτά επι τη ευκαιρία, να μαθαίνουμε όλοι. Όχι σαν μομφή απέναντι στον @SomniusX, που τον ευχαριστώ για την συμμετοχή του.

2 «Μου αρέσει»

μπορείς να σώσεις τον κώδικα σαν κείμενο (αντί για την προεπιλεγμένη συμπίεση) με την επιλογή a αν θυμάμαι καλά. δλδ

SAVE "XMASTREE.BAS", a

μετά το διαβάζεις και το αντιγράφεις από το κανονικό σύστημα.
(και ξαφνικά σκέφτομαι ότι δεν θυμάμαι αν βάζουμε κατάληξη .bas για save/load)
:stuck_out_tongue:

Το LOAD επίσης απλά διαβάζει και κείμενο, απλά πρόσεχε την διαφορά σύμβασης DOS/UNIX.

3 «Μου αρέσει»

Αφού δεν κάνει κάτι ως root ούτε ζητάει elevated privs…

Αλλά έχεις όμως ένα δίκιο, έτσι σπάνε διανομές και φωνάζουν μετά όταν κάποιος buildάρει source που δεν έχει testαριστεί και άλλα.

Εκτός κλίματος και εποχής, αλλά λόγω άφθονου χρόνου :

#!/usr/bin/python

def tree(height):
    width=2*int(height)+1
    line=width*" "
    array=list(line)
    for i in range (0,int(height)):
    	for j in range (0,width):
    		if j==int(width/2):
    			if i==0:
    				array[j]="|"
    			else:
    				array[j-i]="*"
    		if j==int(width/2)+1:
    			if i==0:
    				array[j]="|"
    			else:
    				array[j+i]="*"
    	line="".join(array)
    	print(line)


tree(input("Give height of tree: "))
2 «Μου αρέσει»

Rust? Αν ναι πες μας λίγο για την εμπειρία σου με την συγκεκριμένη Γλώσσα.

Αν μιλάς για τον κώδικα της λύσης μου δεν είναι γραμμένος σε Rust. Είναι γραμμένος σε C++. Τα μοντέρνα χαρακτηριστικά της C++ κάνουν την χρήση της STL παιγνιδάκι, και την φέρνουν αρκετά κοντά στην εκφραστικότητα της Python. Με μια μικρή διαφορά όμως, στην απόδοση. Κοίταξα τον παραγόμενο κώδικα σε assembly με την ελπίδα να βρω μόνο μια σειρά απο κλήσεις στην puts, δεν το βρήκα αυτό, έχει μια πολυπλοκότητα και δεν είναι τα πάντα που χρήσιμοποιώ constexpr ακόμα, αλλά ποιος μπορεί να ξέρει στο μέλλον.

Η C++ είναι σήμερα μια καινούργια γλώσσα, σταμάτα να την θεωρείς απλά σαν μια αντικειμενοστραφή γλώσσα, δεν είναι μόνο αυτό και το μεγαλύτερο μέρος της βιβλιοθήκης της δεν είναι ατελείωτες ιεραρχίες αντικειμένων. H C++ είναι κυρίως γενικός προγραμματισμός (τα templates και ο meta προγραμματισμός με αυτά) αν θέλεις μια ταμπέλα, αλλά στην πραγματικότητα θέλεις πολλές. Μια από αυτές είναι και η συναρτησιακή ταμπέλα που χρησιμοποιώ στο παράδειγμα.

Αλλά δεν ρώτησες για την C++, ρώτησες για την Rust. Η επαφή μου με την Rust είναι λίγο παλιά, και δεν την παρακολουθώ στενά τα τελευταία 2 χρόνια αλλά μου άρεσε σχεδόν οσο και η ruby. Το ερώτημα για μένα στο αν αξίζει να μάθεις μια γλώσσα είναι το εξής

Σε τι θα αλλάξει ο τρόπος σκέψης μου όταν μάθω αυτή την γλώσσα; Τι θα πάρω από αυτήν μαζί μου όταν προγραμματίζω σε άλλες γλώσσες;

Αυτό το κριτήριο δεν είναι γενικό και μπορείς να έχεις άλλους λόγους να μάθεις PHP αλλά στην Rust έχει μια πολύ ωραία απάντηση. Το μοντέλο ιδιοκτησίας της μνήμης. Και αν μάθεις αυτό δεν θέλεις μετά ένα garbage collector. Αν αρχίσεις να σκέφτεσαι με το σε ποιον ανήκει αυτή η μνήμη, τα προβλήματα με την διαχείριση της θα λυθούν χωρίς τα προβλήματα που έχει ένας garbage collector.

Το δεύτερο που παίρνεις μαζί είναι ο έλεγχος ορθότητας του προγράμματος και η χρήση μεταβλητών που μπορούν να έχουν τιμή ή να μην έχουν, χωρίς να μπορείς να αγνοήσεις την δεύτερη περίπτωση.

Και έχει και πολλές άλλες χάρες. Οπότε ναι αξίζει τον κόπο.

4 «Μου αρέσει»

Δε βρίσκω την υλοποίηση που είχα γράψει σε python οπότε πάρτε μια χαζή λύση σε C

#include <stdio.h>
char repeat_string(int a, char * b);
char repeat_empty_space(int a);

int main(){
    int i;
    int n1 = 10;
    char * c1 = "*";
    for (i=0; i<n1; i++){
        repeat_empty_space(i);
        repeat_string(i, c1);
        printf("||");
        repeat_string(i, c1);
        printf("\n");
    }
    return 0;

}

char repeat_string(int a, char * b){
    int i;
    for (i=0; i<a; i++){
        printf("%s",b);

        }
}

char repeat_empty_space(int a){
     int i;
     for (i=10; i>a; i--){
             printf(" ");
     }

}
1 «Μου αρέσει»

Γιατί όχι

inline repeat_empty_space(int a) {
   repeat_string(a, " ");
}

Γιατί πολύ απλά δε γνώριζα το function χαχα

edit no1: από ότι φαίνεται δε μου βγαίνει σωστό δέντρο με αυτή τη συνάρτηση
edit no2 : πάρτε και μια python

height=int(input("Δώσε ύψος του δέντρου : "))

def sides(i):
	return (i*"*")

for i in range(0,int(height)):
	if i == 0:
		print((height)*" ","<||>")
	elif i<height-1:
		print((height-i)*" ",sides(i),"||",sides(i))
	else:
		print((height-2)*" ","|==||==|")```

Κάλιο αργά παρά ποτέ :slightly_smiling_face:
Κάθε φορά που το τρέχουμε τα στολίδια είναι σε διαφορετική θέση.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LINES 5

int main(void) {
int i, k=1, m=0, a=3;
srand(time(NULL));
   for (i = 1 ; i <= LINES ; i++)  {
      while (m < (LINES-i)) {
         putchar(32) ;
         m++ ;
      }
      m = 0 ;
      while (k <= (2*i-1)) {
         if (k == a) {
            putchar('@') ;
            k++ ;
         }
         else {
            putchar(42) ;
            k++ ;
         }
      }
      a = rand() % (2*(i+1)-1) + 1 ;
      k = 1 ;
      printf ("\n") ;
   }
   while (m < (LINES - 2)) {
      putchar(32) ;
      m++ ;
   }
   m = 0 ;
   while (k <= 3) {
      putchar('|') ;
      k++ ;
   }
   k = 1 ;
   printf ("\n") ;
}

3 «Μου αρέσει»

Αρχίσαμε το στόλισμα? :christmas_tree:

5 «Μου αρέσει»