Εδώ Cyberpunk, εκεί Cyberpunk 2077… Η ανάλυση που κατέληξε MSTing

*Μαέστρο, βάλε τη μουσική υπόκρουσις*

Προσωπικά έχω τη χείριστη άποψη για την CD Projekt Red. Μια προσεκτική μελέτη της ιστορίας της, πίσω από το ιλλουστρασιόν περιτύλιγμα, με κάνει να υποψιάζομαι ότι ισχύει γι’αυτήν το κυνικό ρητό που είχα ακούσει από παλιό συνάδελφο με γνώση ή μήπως ήταν ο Βασίλης Ραφαηλίδης;: «Η τέλεια απάτη δεν μπορεί να ξεχωρίσει δια γυμνού οφθαλμού από μια πετυχημένη επιχείρηση». Ενας συνδυασμός αλληλοκολακείας μεταξύ της εταιρείας και των αποκτηνωμένων χουλιγκάνων του GamerGate με κλεισίματα του ματιού στην alt-right, εργασιακών συνθήκων μεταξύ γαλέρας και χαμαιτυπείου της Τρούμπας και αρπαγής επιδοτήσεων ευρωπαϊκών και τοπικών (από μια ακροδεξιά κυβέρνηση, να υπενθυμίσω) δημιούργησαν ένα επιχειρησιακό μοντέλο με εξαιρετικό PR και άριστες οικονομικές επιστροφές, το οποίο όμως στο εσωτερικό του νοσεί. Και δε θέλω να αναφέρω τις υποψίες μου για το πως η εταιρεία εκμεταλλεύτηκε την καλή θέληση εταιρείας RPG  της οποίας η CDPR υπήρξε μεταπωλήτρια και της οποίας τo engine χρησιμοποίησε για το πρώτο της παιχνίδι.

(*ακολουθεί δήθεν τυχαίο βίντεο που συνοψίζει τα διαγραμμένα*)

Λοιπόν, προσφάτως η πανέντιμη αυτή εταιρεία ανέβασε ένα, ομολογουμένως πολυ εντυπωσιακό gameplay demo. Δεν ξέρω αν προσπάθησε, συνειδητά η ασυνείδητα να αντιγράψει την εταιρία RPG που της έδωσε το πρώτο engine και η οποία βρίσκεται τώρα στα κλεισίματα (αποφάσισα να τη λέω με κωδικό «Ντάνκαν»), επιλέγοντας για το gameplay τον custom θηλυκό χάρακτήρα όπως έκανε και η «Ντάνκαν» για το πιο πρόσφατο παιχνίδι της το οποίο χτυπήθηκε σφόδρα από το Nickelback effect. Θα μπορούσε να είναι σύμπτωση, υποσυνείδητος φόρος τιμής ή dogwhistle. Το αφήνω να περάσει με ένα σήκωμα του φρυδιού. ´Η μάλλον δύο, γιατί τώρα που το βλέπω, ο default αρσενικός χαρακτήρας μοιάζει εξαιρετικά σε έναν ΠΟΛΥ εικονικό χαρακτήρα της «Ντάνκαν» μέχρι και στην ουλή στο αριστερό μέρος του τριχωτού της κεφαλής. Αν εννοείτε τι εννοώ.

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

Ο εκφωνητής αναφέρει ότι, «αποφασίσαμε να σας δώσουμε προοπτική πρώτου προσώπου για να βοηθήσουμε την ένταξή σας στα δρώμενα» (για να μην πω «first person perspective» και «immersion»). Και τότε μου μπήκανε ψύλλοι στ’αυτιά και το σκέφτηκα λίγο. Αφού στον Γουιτσερίνιο μια χαρά προοπτική τρίτου προσώπου είχαν.  Και μου ήρθε.

Η προοπτική πρώτου προσώπου είναι πολύ ευκολότερη στον επεξεργαστή, το rendering, και το animation  από την προοπτική τρίτου προσώπου, γι’αυτό έχουμε και περισσότερα First Person Shooters από Third Person Shooters. Ουσιαστικά, αντί να κάνεις rendering τον χαρακτήρα, κάνεις τα χέρια του, που είναι το ένα δέκατο ενός πλήρους μοντέλου. Για έναν Player character που πρέπει να δώσεις προσοχή στη λεπτομέρεια, μιλάμε για τρελή βελτιστοποίηση. Επιπλέον, δεν χρειάζεται να κάνεις animate και lipsync στο πρόσωπο επι τόπου (που η CDPR κατά τα φαινόμενα έχει αναπτύξει ή κλέψει ή αγοράσει ή… δε θα το ψειρίσω τώρα) ή να δείξεις τον custom body type.

Υποψία μου είναι ότι τα lipsync και animation plugins της CDPR αρχισαν να συμπεριφέρονται απρόβλεπτα με την κακή έννοια όταν ένα custom morphed μοντέλο έγινε plugged in πάνω τους. Το ίδιο ακριβώς έπαθε και η «Ντάνκαν» με τα bugs στο facial animation. Περαιτέρω δε μιλάω, γιατί κυκλοφορούν και δικαστικοί επιμελητές. Οπότε, φρονίμως ποιώντες οι Πολωνοί το γύρισαν στην προοπτική πρώτου προσώπου. Εμ βελτιστοποίηση, εμ το customization του χαρακτήρα υποβιβάζεται σε ένα ζευγάρι αντρικά και ένα ζευγάρι γυναικεία χέρια. O custom χαρακτήρας μένει μόνο για τις scripted σκηνές, όπου μπορείς να έχεις το plugin  στράτα-στρατούλα ή να κάνεις pre-render. Για τους NPC, μπορείς να ρίξεις ανάλυση ευσχήμως γιατί δε θα τους πολυπροσέξει κανείς, υπό τον όρο τα ΒΗΖΓΗΑ και οι ΓΚΩΛΟΙ να φαίνονται ωραία.

Nice work, masked magician!

Και μια και είπαμε ΒΗΖΓΗΑ, κάτι που μου χτύπησε εξαιρετικά άσχημα ήταν η αναφορά στον συνωμοσιολογικό αστικό μύθο με τον τύπο που χάνει τις αισθήσεις του και συνέρχεται σε ένα μπάνιο γεμάτο με πάγο και το νεφρό του να λείπει. Ουσιαστικά η γκόμινα που ψάχνεις στην πρώτη σου αποστολή, βρίσκεται εντέχνως βυθισμένη (να φαίνονται τα ΒΗΖΓΗΑ για να την παίξει ο incel GGater που δεν του κάθεται ούτε η χούφτα του) σε μια μπανιέρα με πάγο και της λείπουν τα εμφυτεύματα. Θέλω να είμαι καλοπροαίρετη και να το αποδώσω σε χοντροκομμένη απόπειρα χούμορ (ελπίζω στη deluxe έκδοση να μας δίνουν δώρο μια γαργαλιέρα βιομηχανική) και όχι σε dog whistle για τους συνωμοσιολόγους του QAnon.

Το άκουσες αυτό το πλουφ; Είναι η φούσκα που μόλις έσκασε.

(*κι εδώ πάει στο διάολο η ανάλυση και συνεχίζω με reaction κείμενο*)

Και συνεχίζει με έναν αντρικό κώλο, γιατί εμείς δεν είμαστε σαν την SJW «Ντάνκαν» και δε δείχνουμε ανωμαλίες (εντάξει, μπορεί να δείξουμε κανα λεσβιακό με τον αρσενικό χαρακτήρα να μπαίνει στη μέση και να τις θεραπεύει από τον ολέθριο σαπφισμό με το Ιαματικόν Φως της Ψωλής Του) και anime αναφορές που ήταν ήδη κουρασμένες το σωτήριον έτος 1999 (το εντελώς WTF Samurai τζάκετ). Μοιάζει σαν κάποιος που δεν έχει πάρει μυρωδιά από το Bubblegum Crisis ή το anime γενικά να προσπαθεί να αναφερθεί σε αυτό. Ή αδέξια προσπάθεια να κολακέψουν τον Mike Pondsmith είναι ή ο ίδιος ο Pondsmith δεν είναι τόσο otaku όσο ισχυρίζεται. Προσωπικά εμένα, σαν παλιά otaku, αυτή η δήθενια μου έφερε ξινίλα και τάση προς έμετο.

Μετά από το δέκατο λεπτό, και χωρίς το context της μάχης δε βλέπουμε ούτε καν τα χέρια του χαρακτήρα μας να πιέζουν πλήκτρα. Εννοείται για το immersion και όχι για να γλιτώσει rendering η μηχανή και να ανεβάσει τα frames σε ανεκτό επίπεδο, σε καμμίά περίπτωση, υπάρχουν και δικαστικοί επιμελητές, ξέρετε…

Αχ, πόσο hardware και Software εριξε η CDPR για να μη σε βλέπω, χαρακτήρα μου!

Και συνεχίζει με αξιοπρεπές animation αν και τα πλήθη βαδίζουν με τον ίδιο βηματισμό τσολιά στο Προεδρικό Μέγαρο. Κατόπιν έχουμε τη γελοία παρουσιάση του NPC Τζάκ, ο οποίος μιλάει και δείχνει σαν ρώσος με εμφύσημα που παριστάνει τον Λατινοαμερικάνο. Αλλά το ξέραμε αυτό. Βλαχιά, δηθενιά και λεβεντομαλακία, ότι ακριβως εισπράττω από το demo αυτού του παιχνιδιού. Και οι λοβοτομημένοι ούγκανοι απο κάτω χειροκροτούν. Κατάντια.

Και μετά από τον Τζάκ, έχουμε την ακόμα πιο γελοία και στερεοτυπική παρουσίαση του κυρίου Dexter, που παρουσιάζεται σαν Mr.T-μάυρος-ράπερ-αλήτης-χοντρός-πηδγηάς , αλλά έχει βιονικό χρυσό χέρι και είναι και πολύ Cyberpunk ρε παιδί μου.  Υπόκωφος ρατσισμός, γελοιότητα και δηθενιά. Και νομίζω ότι τον έκανε voice over ο ίδιος ο Pondsmith. Μάλλον πρέπει να πάρω σοβαρά και τη δεύτερη εκδόχη του προηγούμενου ερωτήματος για τον Pondsmith: ότι είναι μυρωδιάς.

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

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

  1. ΔΕΝ ΥΠΑΡΧΕΙ ΠΕΡΙΠΤΩΣΗ ΝΑ ΜΗΝ ΓΙΝΕΙ DOWNGRADE ΤΩΝ ΓΡΑΦΙΚΩΝ ΠΟΥ ΔΕΙΧΝΕΙ ΤΟ TRAILER. Το μηχάνημα στο οποίο έτρεξε το παιχνίδι είναι εξαιρετικά high-end (i7 8700K και nVidia TX1080) και δεδομένου ότι δεν έχουμε καμμια επαναστατική τεχνολογία που θα επιτρέψει διπλασιασμό αποδόσεων τον επόμενο χρόνο, σε δύο χρόνια και πάλι δε θα είναι εύκολο να έχει κανείς τέτοια απόδοση στο rig. Δεδομένης της λαθροχειρίας που έκαναν σε αυτό τον εξοπλισμό, επιλέγοντας πονηρά την προοπτική πρώτου προσώπου, πιστευω ότι θα αναγκαστούν να ριξουν αισθητά την ποιότητα των γραφικών τους αν θέλουν να τρέξουν σε μέσο εξοπλισμό ή/και σε κονσόλα. Το έχουν ξανακάνει στο Γουιτσερίνιο και θα το κάνουν και τώρα. Το εγγυώμαι. Και είμαι σχεδόν σίγουρη ότι έκαναν και άλλες λαθροχειρίες (prerendering, βελτιστοποιήσεις για το συγκεκριμένο χαρακτήρα και το συγκεκριμένο δέντρο επιλογών κτλ.) που δεν θα μπορούν να κάνουν στο προϊον που θα εκδοθεί τελικά.
  2. Ήδη, η επιλογή της προοπτικής πρώτου προσώπου προδίδει ότι η CDPR έχει πέσει σε σοβαρότατα προβλήματα με το animation προσώπων σε συνδυασμό με το character morphing. Πρόκειται για έναν από τους πιο περίπλοκους, δύσκολους και πονηρούς τομείς του 3d animation. Θεωρώ εξαιρετικά πιθανό ότι θα έχουμε ομορφιές σαν κι αυτές που είδαμε τον Απρίλιο του 2017 και μπολικες φάσεις «my face is tired».

Για το ιδεολογικό και καλλιτεχνικό κομμάτι, δε θα πω τίποτε παραπάνω από όσα είπα στο reaction. Η δηθενιά, η κλισεδούρα και η ευτέλεια δεν καλύπτονται με πιστολίδι ούτε γίνονται νουάρ μ’ένα βυζί, έναν αντρικό κώλο, ένα τσιγάρο κι ένα τζάκετ Samurai (έλεος!). Και δεν θα πω παραπάνω για το ρατσισμό και το σεξισμό, ήδη θα με κάνουν προσάναμμα στην πυρά που θα κάψουν την Ανίτα.

Ο Κόκκινος βασιλιάς είναι γυμνός, βρωμόκωλος και μικροτσούτσουνος, αλλά δεν περιμένω από κανέναν να το δεί.

Advertisements

Ενας RoboDM της πλακός με βάση το προηγούμενο randomizer…

…τυπικά μέρος 2ο από κάμποσα.

Ο παρακάτω κώδικας, αηδώς σχολιασμένος, είναι μια δοκιμαστική εφαρμογούλα για το προηγούμενο library  της πλακός και δίνει ένα πρόχειρο text interface για να παίξετε ένα RPG με το σύστημα του Tiny Solitary Soldiers.

Δεν έρχεται με χαρακτήρες και ιστορία, ο παίχτης τα φτιάχνει μόνος του. Στο τέλος το προγραμματάκι τυπώνει μια σύνοψη του τι έκανε η παιχτούρα και τι ιστορία έφτιαξε…

// testrpg project main.go
package main

import (
	"fmt"
	"rpg"
	"strings"
//had to add these to create a decent description scanner
	"bufio"
	"os"
)



func main() {
	var readMe string
//Description
	fmt.Println("This is your sad Solo RPG DM")
	fmt.Println("Created from boredom and despair by StormCloud71.")
	fmt.Println("Valid commands are: 'Roll' to roll dice, 'Desc' to add a description,'Quit' to Quit");

//initializing
	response:="cont"
	turn:=1
	output:="Begin: "
	inputScan:=bufio.NewScanner(os.Stdin)
//main loop
	for ;response!="quit"; {
		fmt.Println("Turn ", turn)
		fmt.Printf("What do you want to do?")
		fmt.Scanln(&response)
		response=strings.ToLower(response)
		switch {
			case response=="desc":
				fmt.Printf("So, what happened? ")
//				fmt.Scanf("%s",&readMe)
				inputScan.Scan()
				readMe=inputScan.Text()
				output=output+readMe+"\n"
			case response=="roll":
				readMe=rpg.SoloRPGAnswer()
				fmt.Println("Player rolled and result was: "+readMe)
				output=output+"Player rolled and result was:"+readMe+"\n"
				if rpg.DiceRoll(6) == 1 {
//bad variable reuse here, cover your eyes kids...
					readMe=rpg.SoloRPGTwist()
					output=output+"And there was that twist:"
					output=output+readMe
					fmt.Println ("And you had this twist:",readMe)
				}
				output=output+"\n"
				turn+=1
			case response=="quit":
				output=output+"...and the player quit right then."+"\n"
			default:
				fmt.Println("Unknown command:",response)
		}
	}
	fmt.Println ("Resume:")
	fmt.Printf(output)
}

 

 

 

Κάτι randomizers σε Golang…

Απλά ήθελα να κάνω λίγο show off…

Οδηγίες: Φτιάχνετε ένα directory rpg στο src, ανοίγετε στον code editor το rpg.go και κοπυπάστα.

Δεν υπόσχομαι τίποτε, αλλά μπορεί να έχω κάτι  βασισμένο στα παρακάτω προσεχώς…

Η ιδέα ξεκίνησε από το απλό αλλά ιδιοφυές σύστημα που περιγράφεται εδώ:

Edit: Τώρα που το βλέπω έχει λαθάκια, αλλά το βασικό δουλεύει.

// rpg project rpg.go
package rpg

/*
	An utility RPG aid package containing dice rollers, character classes and
	whatever caught my fancy.
	Use at your own risk.
*/

import (
	"math/rand"
	"time"
)

type RPGActor struct {
	Name  string
	Descr string
	Attr  map[string]int
	Skill map[string]int
}

/*
//must try that and see how to make it

func (myActor RPGActor) MakeRandom () RpgActor {
	var mNames = [5]string {"Ulfric","Eiric","Odo","Frigg", "Elspeth"}
	newActor=make(RPGActor)
}
*/

func RollzInit() {
	//initialize random generator with current time
	rand.Seed(time.Now().UTC().UnixNano())
}

func FudgeTranslate(roll int) string {
	//Translate a fudge number to a fudge verbal
	var verbals = [9]string{"Horrible", "Terrible", "Bad", "Mediocre", "Fair", "Good", "Great", "Superb", "Legendary"}
	if roll >= -4 && roll <= 4 {
		return verbals[roll+4]
	} else {
		return "Invalid number"
	}
}

func FudgeRoll() int {
	//a standard fudge dice roll, four dice
	finalres := 0
	for i := 1; i <= 4; i++ { 		finalres = finalres + rand.Intn(3) - 1 	} 	return finalres } func DiceRoll(sidez int) int { 	//generic dice roll, sidez is the number of sides for the dice 	if sidez > 0 {
		return (rand.Intn(sidez) + 1)
	} else {
		return 0
	}
}

func SoloRPGAnswer() string {
	//Tiny Solitary soldiers Solo RPG answers
	var answers = [6]string{"No and", "No", "No But", "Yes but", "Yes", "Yes And"}
	return answers[rand.Intn(6)]
}

func SoloRPGTwist() string {
	//Tiny Solitary soldiers Solo RPG Twists
	//the following should become iotas in a separate type, but I'll take them as
	//they are for now, because, honestly I want to run something on Go

	var resource = [6]string{"NPC", "PC", "Organization", "Physical Event", "Emotional Event", "Item"}
	var actionz = [6]string{"appears", "alters location", "helps hero", "hinders hero", "changes goal", "Ends scene"}
	return resource[rand.Intn(6)] + " " + actionz[rand.Intn(6)]
}

func SoloRPGScene() string {
	choice:=rand.Intn(6)
	switch choice {
		case 0:
			return("Meanwhile...")
		case 1:
			fallthrough
		case 2:
			return("Quiet Scene")
		default:
			return("Dramatic Scene")
	}
}

 

Αυτή η παλιά άσκηση με τα δυαδικά δέντρα…

Το κλασσικό σορτάρισμα με δυαδικό δέντρο σε Golang.

Ναι, η test case είναι αυτή και ναι, την εμπνεύστηκα απο αυτό το σκέτς που καταλάβατε.

package main

import (
 "fmt"
 "strings"
 )

type TreeNode struct {
 myText string
 lnode *TreeNode
 rnode *TreeNode
 }

func AddLeaf(x *TreeNode, myStr string) {
 var newNode TreeNode
 if x.myText > myStr {
 if x.lnode == nil {
 newNode = TreeNode{myText: myStr}
 x.lnode = &newNode
 } else {
 AddLeaf(x.lnode, myStr)
 }
 } else {
 if x.rnode == nil {
 newNode = TreeNode{myText: myStr}
 x.rnode = &newNode
 } else {
 AddLeaf(x.rnode, myStr)
 }

}

}

func PrintSort(x *TreeNode) {
 if x.lnode != nil {
 PrintSort(x.lnode)
 }
 fmt.Println(x.myText)
 if x.rnode != nil {
 PrintSort(x.rnode)
 }
 }

func main() {
 var mytree TreeNode
 wordlist := strings.Split("ΑΕΤΟΣ ΑΔΡΑΧΤΙ ΛΙΜΕΝΟΦΥΛΑΚΑΣ ΝΥΧΟΚΟΠΤΗΣ ΜΠΡΕΛΟΚ ΑΝΕΜΟΓΚΑΣΤΡΙ ΑΒΕΣΣΑΛΩΜ ΙΣΤΙΟΠΛΟΟΣ ΧΩΡΙΣΤΡΑ", " ")

mytreecur := &mytree
 mytreecur.myText = wordlist[0]
 for i := 1; i < len(wordlist); i++ {
 AddLeaf(mytreecur, wordlist[i])
 }

PrintSort(mytreecur)

}

Σκονάκια

Η προγραμματιστική άσκηση ήταν κάτι που με τσίγκλισε. Τον τελευταίο καιρό προσπαθώ να κάνω κάτι ταρζανιές λίγο περίεργες (περιλαμβάνουν κάμποσο CSS, ολίγη Javascript, μια μυρωδιά HTML και πολύ-πολύ μακαρονικό κώδικα), οπότε, όταν απομακρύνομαι απο το χάος, προσπαθώ να παίξω με άλλα πραγματάκια. Ας πούμε Python…  ή Go.

Λοιπόν με αυτή την Go έπαθα ότι με το Mass Effect. Της έριξα μια ματιά στην αρχή, δε μου έκανε κούκου, την παραμέρισα, παπαρίστηκα με διάφορα άλλα άσχετα, και λίγο καιρό μετά, την ξαναείδα με φρέσκο μάτι και πολύ με άρεζε. Αλλά, παρασύρομαι, είμαι και σε ηλικία που αρχίζει ο γερμανός και σου παίρνει τα μυαλά, οπότε, ας μπούμε στο θεμα.

Η άσκηση ήταν κατά τα φαινόμενα απλή. Θυμάστε το Πυθαγόρειο Θεώρημα από το Λύκειο; «Το τετράγωνον της υποτεινούσης ισούται με το άθροισμα των τετραγώνων των δύο κάθετων πλευρών«; Ελπίζω να μην κάνω summon τον LAMAG αυτή τη στιγμή...  Γενικά ο αριθμός που αντιστοιχεί στο τετράγωνο της υποτείνουσας δεν έχει σα ρίζα ακέραιο αριθμό, πράγμα που πολύ εσκότισεν τον Πυθαγόρα μόλις το πήρε χαμπάρι. Όμως, σε κάποιες, άρκετες περιπτώσεις, τυχαίνει.  Να, π.χ.  To Τρίγωνο με πλευρές 3 και 4 μονάδων έχει υποτείνουσα 5 μονάδες:

path4165

Αυτή λοιπόν η τριάδα (3,4,5) λέγεται Πυθαγόρεια τριάδα. Η άσκηση μας ζητάει να βρούμε τη μία και μοναδική τριάδα (α,β,γ) όπου α+β+γ=1000.

Ούπς!

Η πρώτη μου ιδέα ήταν να δω αν υπάρχει κάτι αλγεβρικό. Αλλά απέχω μια ζωή από το Λύκειο και το Πανεπιστήμιο και με έπιασε απελπισία. Οπότε, η πρώτη μου απόπειρα σε Python ήταν το ακόλουθο αίσχος:

squares={i:i*i for i in range(1,500)}
invsquares={squares[i]:i for i in squares}
for i in range (1,500):
    for j in range(i,500):
        if (i*i+j*j) in invsquares:
            k=invsquares[(i*i+j*j)]
            if i+j+k==1000: print (i,j,k)

Είναι νομίζω ψιλοσαφές τι κάνω, και ζητώ συγγνώμη για τυχόν ανατριχίλες που νιώσατε. Ίσως θα μπορούσα να κάνω και τα for..next comprehensions, αλλά βιαζόμουνα. Δεν έχει σημασία, μερικές φορές σημασία έχει να βγάλεις κώδικα και αποτέλεσμα γρήγορα, και μετά να ανησυχείς για το πόσο έξυπν@ θα φανείς και πόσα comprehension θα δέσεις σε αλυσίδα.

Απλό, λιτό, κατανοητό, αλλά… είμαι μόλις μισή βδομάδα με την Go, και δεν το έχω και τόσο στα arrays. Τι να κάνουμε λοιπόν… τι να κάνουμε;

Ιδέα. Μια συνάρτηση που να βρίσκει την ακέραια ρίζα ενός ακεραίου (αν αυτή υπάρχει). Οπότε, κρατάμε το for loop και απλά, αντί να ψάχνουμε το λεξικό, βλέπουμε επι τόπου αν έχουμε πυθαγόρεια τριάδα.

Οπότε, έχοντας φτιάξει προηγουμένως ένα πρωτοτυπάκι σε Python, έφτιαξα το ακόλουθο προγραμματάκι σε  Go:

package main

import "fmt"

func intSqrt(x int) int {
 var result=-1
 if (x==0 || x==1) {
 result=x
 } else {
 llim,ulim:=0,x
 not_found:=true
 var csr int
 csr=x/2
 for not_found {
 if csr*csr==x {
 not_found=false
 result=csr
 } else if csr*csr>x {
 ulim=csr
 csr=(ulim+llim)/2
 } else {
 llim=csr
 csr=ulim+llim/2
 }
 if ulim-1<=llim {not_found=false} 
 }
 
 }
 return result
}

func main() {
 var a,b,c int
 for i:=1;i<=500;i++ {
 for j:=i;j<=500;j++{
 k:=intSqrt(i*i+j*j)
 if k!=-1 {
 a=i
 b=j
 c=k
 if (a+b+c==1000) {fmt.Println("Η πυθαγόρεια τριάδα με άθροισμα 1000 είναι η: ",a,b,c)}}
 }
 }
 }

Είναι θλιβερό, είναι γάμησέ τα, αλλά την Πυθαγόρειο τριάδα τη βρήκε μια χαρούλα.

Ποια γλώσσα είναι καλύτερη;

Εξαρτάται, αλλά βρήκα ότι μου αρέσει πιο πολύ η σαφήνεια και η περιεκτικότητα της Python. Βέβαια, αν θέλω ασφάλεια, ταχύτητα και compiled κώδικα, εννοείται ότι θα πάω σε Go.