Display a linear combination

Display a linear combination is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Display a finite linear combination in an infinite vector basis ${\displaystyle (e_{1},e_{2},\ldots )}$.

Write a function that, when given a finite list of scalars ${\displaystyle (\alpha ^{1},\alpha ^{2},\ldots )}$,
creates a string representing the linear combination ${\displaystyle \sum _{i}\alpha ^{i}e_{i}}$ in an explicit format often used in mathematics, that is:

${\displaystyle \alpha ^{i_{1}}e_{i_{1}}\pm |\alpha ^{i_{2}}|e_{i_{2}}\pm |\alpha ^{i_{3}}|e_{i_{3}}\pm \ldots }$

where ${\displaystyle \alpha ^{i_{k}}\neq 0}$

The output must comply to the following rules:

•   don't show null terms, unless the whole combination is null.
e(1)     is fine,     e(1) + 0*e(3)     or     e(1) + 0     is wrong.
•   don't show scalars when they are equal to one or minus one.
e(3)     is fine,     1*e(3)     is wrong.
•   don't prefix by a minus sign if it follows a preceding term.   Instead you use subtraction.
e(4) - e(5)     is fine,     e(4) + -e(5)     is wrong.

Show here output for the following lists of scalars:

 1)    1,  2,  3
2)    0,  1,  2,  3
3)    1,  0,  3,  4
4)    1,  2,  0
5)    0,  0,  0
6)    0
7)    1,  1,  1
8)   -1, -1, -1
9)   -1, -2,  0, -3
10)   -1


C

Accepts vector coefficients from the command line, prints usage syntax if invoked with no arguments. This implementation can handle floating point values but displays integer values as integers. All test case results shown with invocation. A multiplication sign is not shown between a coefficient and the unit vector when a vector is written out by hand ( i.e. human readable) and is thus not shown here as well.

  #include<stdlib.h>#include<stdio.h>#include<math.h> /*Optional, but better if included as fabs, labs and abs functions are being used. */ int main(int argC, char* argV[]){ 	int i,zeroCount= 0,firstNonZero = -1;	double* vector; 	if(argC == 1){		printf("Usage : %s <Vector component coefficients seperated by single space>",argV[0]);	} 	else{ 		printf("Vector for [");		for(i=1;i<argC;i++){			printf("%s,",argV[i]);		}		printf("\b] -> ");  		vector = (double*)malloc((argC-1)*sizeof(double)); 		for(i=1;i<=argC;i++){			vector[i-1] = atof(argV[i]);			if(vector[i-1]==0.0)				zeroCount++;			if(vector[i-1]!=0.0 && firstNonZero==-1)				firstNonZero = i-1;		} 		if(zeroCount == argC){			printf("0");		} 		else{			for(i=0;i<argC;i++){				if(i==firstNonZero && vector[i]==1)					printf("e%d ",i+1);				else if(i==firstNonZero && vector[i]==-1)					printf("- e%d ",i+1);				else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])>0.0)					printf("- %lf e%d ",fabs(vector[i]),i+1);				else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])==0.0)					printf("- %ld e%d ",labs(vector[i]),i+1);				else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])>0.0)					printf("%lf e%d ",vector[i],i+1);				else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])==0.0)					printf("%ld e%d ",vector[i],i+1);				else if(fabs(vector[i])==1.0 && i!=0)					printf("%c e%d ",(vector[i]==-1)?'-':'+',i+1);				else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])>0.0)					printf("%c %lf e%d ",(vector[i]<0)?'-':'+',fabs(vector[i]),i+1);				else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])==0.0)					printf("%c %ld e%d ",(vector[i]<0)?'-':'+',labs(vector[i]),i+1);							}		}	} 	free(vector); 	return 0;}
Output:
C:\rossetaCode>vectorDisplay.exe 1 2 3
Vector for [1,2,3] -> e1 + 2 e2 + 3 e3
C:\rossetaCode>vectorDisplay.exe 0 0 0
Vector for [0,0,0] -> 0
C:\rossetaCode>vectorDisplay.exe 0 1 2 3
Vector for [0,1,2,3] -> e2 + 2 e3 + 3 e4
C:\rossetaCode>vectorDisplay.exe 1 0 3 4
Vector for [1,0,3,4] -> e1 + 3 e3 + 4 e4
C:\rossetaCode>vectorDisplay.exe 1 2 0
Vector for [1,2,0] -> e1 + 2 e2
C:\rossetaCode>vectorDisplay.exe 0 0 0
Vector for [0,0,0] -> 0
C:\rossetaCode>vectorDisplay.exe 0
Vector for [0] -> 0
C:\rossetaCode>vectorDisplay.exe 1 1 1
Vector for [1,1,1] -> e1 + e2 + e3
C:\rossetaCode>vectorDisplay.exe -1 -1 -1
Vector for [-1,-1,-1] -> - e1 - e2 - e3
C:\rossetaCode>vectorDisplay.exe -1 -2 0 -3
Vector for [-1,-2,0,-3] -> - e1 - 2 e2 - 3 e4
C:\rossetaCode>vectorDisplay.exe -1
Vector for [-1] -> - e1


D

Translation of: Kotlin
import std.array;import std.conv;import std.format;import std.math;import std.stdio; string linearCombo(int[] c) {    auto sb = appender!string;    foreach (i, n; c) {        if (n==0) continue;        string op;        if (n < 0) {            if (sb.data.empty) {                op = "-";            } else {                op = " - ";            }        } else if (n > 0) {            if (!sb.data.empty) {                op = " + ";            }        }        auto av = abs(n);        string coeff;        if (av != 1) {            coeff = to!string(av) ~ "*";        }        sb.formattedWrite("%s%se(%d)", op, coeff, i+1);    }    if (sb.data.empty) {        return "0";    }    return sb.data;} void main() {    auto combos = [        [1, 2, 3],        [0, 1, 2, 3],        [1, 0, 3, 4],        [1, 2, 0],        [0, 0, 0],        [0],        [1, 1, 1],        [-1, -1, -1],        [-1, -2, 0, -3],        [-1],    ];    foreach (c; combos) {        auto arr = c.format!"%s";        writefln("%-15s  ->  %s", arr, linearCombo(c));    }}
Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

EchoLisp

 ;; build an html string from list of coeffs (define (linear->html coeffs)    (define plus #f)     (or*     (for/fold (html "") ((a coeffs) (i (in-naturals 1)))      (unless (zero? a) 		(set! plus (if plus "+" "")))      (string-append html	 (cond 	  ((= a 1)  (format "%a e<sub>%d</sub> " plus i))	  ((= a -1) (format "- e<sub>%d</sub> " i))	  ((> a 0)  (format "%a %d*e<sub>%d</sub> " plus a i))	  ((< a 0)  (format "- %d*e<sub>%d</sub> " (abs a) i))	  (else ""))))     "0")) (define linears '((1 2 3)   (0 1 2 3)   (1 0 3 4)   (1 2 0)   (0 0 0)   (0)   (1 1 1)   (-1 -1 -1)   (-1 -2 0 -3)   (-1))) (define (task linears)    (html-print ;; send string to stdout    (for/string ((linear linears))      (format "%a -> <span style='color:blue'>%a</span> <br>" linear (linear->html linear)))))
Output:

(1 2 3) -> e1 + 2*e2 + 3*e3
(0 1 2 3) -> e2 + 2*e3 + 3*e4
(1 0 3 4) -> e1 + 3*e3 + 4*e4
(1 2 0) -> e1 + 2*e2
(0 0 0) -> 0
(0) -> 0
(1 1 1) -> e1 + e2 + e3
(-1 -1 -1) -> - e1 - e2 - e3
(-1 -2 0 -3) -> - e1 - 2*e2 - 3*e4
(-1) -> - e1

Elixir

Works with: Elixir version 1.3
defmodule Linear_combination do  def display(coeff) do    Enum.with_index(coeff)    |> Enum.map_join(fn {n,i} ->         {m,s} = if n<0, do: {-n,"-"}, else: {n,"+"}         case {m,i} do           {0,_} -> ""           {1,i} -> "#{s}e(#{i+1})"           {n,i} -> "#{s}#{n}*e(#{i+1})"         end       end)    |> String.trim_leading("+")    |> case do         ""  -> IO.puts "0"         str -> IO.puts str       end  endend coeffs =   [ [1, 2, 3],    [0, 1, 2, 3],    [1, 0, 3, 4],    [1, 2, 0],    [0, 0, 0],    [0],    [1, 1, 1],    [-1, -1, -1],    [-1, -2, 0, -3],    [-1]  ]Enum.each(coeffs, &Linear_combination.display(&1))
Output:
e(1)+2*e(2)+3*e(3)
e(2)+2*e(3)+3*e(4)
e(1)+3*e(3)+4*e(4)
e(1)+2*e(2)
0
0
e(1)+e(2)+e(3)
-e(1)-e(2)-e(3)
-e(1)-2*e(2)-3*e(4)
-e(1)


F#

The function

 // Display a linear combination. Nigel Galloway: March 28th., 2018let fN g =  let rec fG n g=match g with                 |0::g    ->                        fG (n+1) g                 |1::g    -> printf "+e(%d)" n;     fG (n+1) g                 |(-1)::g -> printf "-e(%d)" n;     fG (n+1) g                 |i::g    -> printf "%+de(%d)" i n; fG (n+1) g                 |_       -> printfn ""  let rec fN n g=match g with                 |0::g    ->                        fN (n+1) g                 |1::g    -> printf "e(%d)" n;      fG (n+1) g                 |(-1)::g -> printf "-e(%d)" n;     fG (n+1) g                 |i::g    -> printf "%de(%d)" i n;  fG (n+1) g                 |_       -> printfn "0"  fN 1 g

 fN [1;2;3]
Output:
e(1)+2e(2)+3e(3)

 fN [0;1;2;3]
Output:
e(2)+2e(3)+3e(4)

 fN[1;0;3;4]
Output:
e(1)+3e(3)+4e(4)

 fN[1;2;0]
Output:
e(1)+2e(2)

 fN[0;0;0]
Output:
0

 fN[0]
Output:
0

 fN[1;1;1]
Output:
e(1)+e(2)+e(3)

 fN[-1;-1;-1]
Output:
-e(1)-e(2)-e(3)

 fN[-1;-2;0;-3]
Output:
-e(1)-2e(2)-3e(4)

 fN[1]
Output:
e(1)


Factor

USING: formatting kernel match math pair-rocket regexp sequences ; MATCH-VARS: ?a ?b ; : choose-term ( coeff i -- str )    1 + { } 2sequence {        {  0  _ } => [       ""                 ]        {  1 ?a } => [ ?a    "e(%d)"    sprintf ]        { -1 ?a } => [ ?a    "-e(%d)"   sprintf ]        { ?a ?b } => [ ?a ?b "%d*e(%d)" sprintf ]    } match-cond ; : linear-combo ( seq -- str )    [ choose-term ] map-index harvest " + " join    R/ \+ -/ "- " re-replace [ "0" ] when-empty ; { { 1 2 3 } { 0 1 2 3 } { 1 0 3 4 } { 1 2 0 } { 0 0 0 } { 0 }  { 1 1 1 } { -1 -1 -1 } { -1 -2 0 -3 } { -1 } }[ dup linear-combo "%-14u  ->  %s\n" printf ] each
Output:
{ 1 2 3 }       ->  e(1) + 2*e(2) + 3*e(3)
{ 0 1 2 3 }     ->  e(2) + 2*e(3) + 3*e(4)
{ 1 0 3 4 }     ->  e(1) + 3*e(3) + 4*e(4)
{ 1 2 0 }       ->  e(1) + 2*e(2)
{ 0 0 0 }       ->  0
{ 0 }           ->  0
{ 1 1 1 }       ->  e(1) + e(2) + e(3)
{ -1 -1 -1 }    ->  -e(1) - e(2) - e(3)
{ -1 -2 0 -3 }  ->  -e(1) - 2*e(2) - 3*e(4)
{ -1 }          ->  -e(1)


Go

Translation of: Kotlin
package main import (    "fmt"    "strings") func linearCombo(c []int) string {    var sb strings.Builder    for i, n := range c {        if n == 0 {            continue        }        var op string        switch {        case n < 0 && sb.Len() == 0:            op = "-"        case n < 0:            op = " - "        case n > 0 && sb.Len() == 0:            op = ""        default:            op = " + "        }        av := n        if av < 0 {            av = -av        }        coeff := fmt.Sprintf("%d*", av)        if av == 1 {            coeff = ""        }        sb.WriteString(fmt.Sprintf("%s%se(%d)", op, coeff, i+1))    }    if sb.Len() == 0 {        return "0"    } else {        return sb.String()    }} func main() {    combos := [][]int{        {1, 2, 3},        {0, 1, 2, 3},        {1, 0, 3, 4},        {1, 2, 0},        {0, 0, 0},        {0},        {1, 1, 1},        {-1, -1, -1},        {-1, -2, 0, -3},        {-1},    }    for _, c := range combos {        t := strings.Replace(fmt.Sprint(c), " ", ", ", -1)        fmt.Printf("%-15s  ->  %s\n", t, linearCombo(c))    }}
Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)


J

Implementation:

fourbanger=:3 :0  e=. ('e(',')',~])@":&.> 1+i.#y  firstpos=. 0< {.y-.0  if. */0=y do. '0' else. firstpos}.;y gluedto e end.) gluedto=:4 :0 each  pfx=. '+-' {~ x<0  select. |x    case. 0 do. ''    case. 1 do. pfx,y    case.   do. pfx,(":|x),'*',y  end.)

Example use:

   fourbanger 1 2 3e(1)+2*e(2)+3*e(3)   fourbanger 0 1 2 3e(2)+2*e(3)+3*e(4)   fourbanger 1 0 3 4e(1)+3*e(3)+4*e(4)   fourbanger 0 0 00   fourbanger 00   fourbanger 1 1 1e(1)+e(2)+e(3)   fourbanger _1 _1 _1-e(1)-e(2)-e(3)   fourbanger _1 _2 0 _3-e(1)-2*e(2)-3*e(4)   fourbanger _1-e(1)

Java

Translation of: Kotlin
import java.util.Arrays; public class LinearCombination {    private static String linearCombo(int[] c) {        StringBuilder sb = new StringBuilder();        for (int i = 0; i < c.length; ++i) {            if (c[i] == 0) continue;            String op;            if (c[i] < 0 && sb.length() == 0) {                op = "-";            } else if (c[i] < 0) {                op = " - ";            } else if (c[i] > 0 && sb.length() == 0) {                op = "";            } else {                op = " + ";            }            int av = Math.abs(c[i]);            String coeff = av == 1 ? "" : "" + av + "*";            sb.append(op).append(coeff).append("e(").append(i + 1).append(')');        }        if (sb.length() == 0) {            return "0";        }        return sb.toString();    }     public static void main(String[] args) {        int[][] combos = new int[][]{            new int[]{1, 2, 3},            new int[]{0, 1, 2, 3},            new int[]{1, 0, 3, 4},            new int[]{1, 2, 0},            new int[]{0, 0, 0},            new int[]{0},            new int[]{1, 1, 1},            new int[]{-1, -1, -1},            new int[]{-1, -2, 0, -3},            new int[]{-1},        };        for (int[] c : combos) {            System.out.printf("%-15s  ->  %s\n", Arrays.toString(c), linearCombo(c));        }    }}
Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

Julia

# v0.6 linearcombination(coef::Array) = join(collect("$c * e($i)" for (i, c) in enumerate(coef) if c != 0), " + ") for c in [[1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1],    [-1, -1, -1], [-1, -2, 0, -3], [-1]]    @printf("%20s -> %s\n", c, linearcombination(c))end
Output:
           [1, 2, 3] -> 1 * e(1) + 2 * e(2) + 3 * e(3)
[0, 1, 2, 3] -> 1 * e(2) + 2 * e(3) + 3 * e(4)
[1, 0, 3, 4] -> 1 * e(1) + 3 * e(3) + 4 * e(4)
[1, 2, 0] -> 1 * e(1) + 2 * e(2)
[0, 0, 0] ->
[0] ->
[1, 1, 1] -> 1 * e(1) + 1 * e(2) + 1 * e(3)
[-1, -1, -1] -> -1 * e(1) + -1 * e(2) + -1 * e(3)
[-1, -2, 0, -3] -> -1 * e(1) + -2 * e(2) + -3 * e(4)
[-1] -> -1 * e(1)

Kotlin

// version 1.1.2 fun linearCombo(c: IntArray): String {     val sb = StringBuilder()    for ((i, n) in c.withIndex()) {        if (n == 0) continue        val op = when {            n < 0 && sb.isEmpty() -> "-"            n < 0                 -> " - "            n > 0 && sb.isEmpty() -> ""            else                  -> " + "        }        val av = Math.abs(n)        val coeff = if (av == 1) "" else "$av*" sb.append("$op${coeff}e(${i + 1})")    }    return if(sb.isEmpty()) "0" else sb.toString()} fun main(args: Array<String>) {     val combos = arrayOf(        intArrayOf(1, 2, 3),        intArrayOf(0, 1, 2, 3),        intArrayOf(1, 0, 3, 4),        intArrayOf(1, 2, 0),        intArrayOf(0, 0, 0),        intArrayOf(0),        intArrayOf(1, 1, 1),        intArrayOf(-1, -1, -1),        intArrayOf(-1, -2, 0, -3),        intArrayOf(-1)    )    for (c in combos) {        println("${c.contentToString().padEnd(15)} ->${linearCombo(c)}")    }}
Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)


Modula-2

MODULE Linear;FROM FormatString IMPORT FormatString;FROM Terminal IMPORT WriteString,WriteLn,ReadChar; PROCEDURE WriteInt(n : INTEGER);VAR buf : ARRAY[0..15] OF CHAR;BEGIN    FormatString("%i", buf, n);    WriteString(buf)END WriteInt; PROCEDURE WriteLinear(c : ARRAY OF INTEGER);VAR    buf : ARRAY[0..15] OF CHAR;    i,j : CARDINAL;    b : BOOLEAN;BEGIN    b := TRUE;    j := 0;     FOR i:=0 TO HIGH(c) DO        IF c[i]=0 THEN CONTINUE END;         IF c[i]<0 THEN            IF b THEN WriteString("-")            ELSE      WriteString(" - ") END;        ELSIF c[i]>0 THEN            IF NOT b THEN WriteString(" + ") END;        END;         IF c[i] > 1 THEN            WriteInt(c[i]);            WriteString("*")        ELSIF c[i] < -1 THEN            WriteInt(-c[i]);            WriteString("*")        END;         FormatString("e(%i)", buf, i+1);        WriteString(buf);         b := FALSE;        INC(j)    END;     IF j=0 THEN WriteString("0") END;    WriteLnEND WriteLinear; TYPE    Array1 = ARRAY[0..0] OF INTEGER;    Array3 = ARRAY[0..2] OF INTEGER;    Array4 = ARRAY[0..3] OF INTEGER;BEGIN    WriteLinear(Array3{1,2,3});    WriteLinear(Array4{0,1,2,3});    WriteLinear(Array4{1,0,3,4});    WriteLinear(Array3{1,2,0});    WriteLinear(Array3{0,0,0});    WriteLinear(Array1{0});    WriteLinear(Array3{1,1,1});    WriteLinear(Array3{-1,-1,-1});    WriteLinear(Array4{-1,-2,0,-3});    WriteLinear(Array1{-1});     ReadCharEND Linear.

sub linear_combination {    my(@coef) = @$_; my$e;    for my $c (1..+@coef) {$e .= "$coef[$c-1]*e($c) + " if$coef[$c-1] }$e =~ s/ \+ $//;$e =~ s/1\*//g;    $e =~ s/\+ -/- /g;$e // 0;} print linear_combination($_), "\n" for [1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, -3], [-1 ] Output: e(1) + 2*e(2) + 3*e(3) e(2) + 2*e(3) + 3*e(4) e(1) + 3*e(3) + 4*e(4) e(1) + 2*e(2) 0 0 e(1) + e(2) + e(3) -e(1) - e(2) - e(3) -e(1) - 2*e(2) - 3*e(4) -e(1) Perl 6 sub linear-combination(@coeff) { (@coeff Z=> map { "e($_)" }, 1 .. *)    .grep(+*.key)    .map({ .key ~ '*' ~ .value })    .join(' + ')    .subst('+ -', '- ', :g)    .subst(/<|w>1\*/, '', :g)        || '0'} say linear-combination($_) for [1, 2, 3],[0, 1, 2, 3],[1, 0, 3, 4],[1, 2, 0],[0, 0, 0],[0],[1, 1, 1],[-1, -1, -1],[-1, -2, 0, -3],[-1 ]; Output: e(1) + 2*e(2) + 3*e(3) e(2) + 2*e(3) + 3*e(4) e(1) + 3*e(3) + 4*e(4) e(1) + 2*e(2) 0 0 e(1) + e(2) + e(3) -e(1) - e(2) - e(3) -e(1) - 2*e(2) - 3*e(4) -e(1) Phix Translation of: Tcl function linear_combination(sequence f) string res = "" for e=1 to length(f) do integer fe = f[e] if fe!=0 then if fe=1 then if length(res) then res &= "+" end if elsif fe=-1 then res &= "-" elsif fe>0 and length(res) then res &= sprintf("+%d*",fe) else res &= sprintf("%d*",fe) end if res &= sprintf("e(%d)",e) end if end for if res="" then res = "0" end if return resend function constant tests = {{1,2,3}, {0,1,2,3}, {1,0,3,4}, {1,2,0}, {0,0,0}, {0}, {1,1,1}, {-1,-1,-1}, {-1,-2,0,-3}, {-1}}for i=1 to length(tests) do sequence ti = tests[i] printf(1,"%12s -> %s\n",{sprint(ti), linear_combination(ti)})end for Output:  {1,2,3} -> e(1)+2*e(2)+3*e(3) {0,1,2,3} -> e(2)+2*e(3)+3*e(4) {1,0,3,4} -> e(1)+3*e(3)+4*e(4) {1,2,0} -> e(1)+2*e(2) {0,0,0} -> 0 {0} -> 0 {1,1,1} -> e(1)+e(2)+e(3) {-1,-1,-1} -> -e(1)-e(2)-e(3) {-1,-2,0,-3} -> -e(1)-2*e(2)-3*e(4) {-1} -> -e(1)  Python  def linear(x): return ' + '.join(['{}e({})'.format('-' if v == -1 else '' if v == 1 else str(v) + '*', i + 1) for i, v in enumerate(x) if v] or ['0']).replace(' + -', ' - ') list(map(lambda x: print(linear(x)), [[1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, 3], [-1]]))  Output: e(1) + 2*e(2) + 3*e(3) e(2) + 2*e(3) + 3*e(4) e(1) + 3*e(3) + 4*e(4) e(1) + 2*e(2) 0 0 e(1) + e(2) + e(3) -e(1) - e(2) - e(3) -e(1) - 2*e(2) + 3*e(4) -e(1)  Racket #lang racket/base(require racket/match racket/string) (define (linear-combination->string es) (let inr ((es es) (i 1) (rv "")) (match* (es rv) [((list) "") "0"] [((list) rv) rv] [((list (? zero?) t ...) rv) (inr t (add1 i) rv)] [((list n t ...) rv) (define ±n (match* (n rv) ;; zero is handled above [(1 "") ""] [(1 _) "+"] [(-1 _) "-"] [((? positive? n) (not "")) (format "+~a*" n)] [(n _) (format "~a*" n)])) (inr t (add1 i) (string-append rv ±n "e("(number->string i)")"))]))) (for-each (compose displayln linear-combination->string) '((1 2 3) (0 1 2 3) (1 0 3 4) (1 2 0) (0 0 0) (0) (1 1 1) (-1 -1 -1) (-1 -2 0 -3) (-1)))  Output: e(1)+2*e(2)+3*e(3) e(2)+2*e(3)+3*e(4) e(1)+3*e(3)+4*e(4) e(1)+2*e(2) 0 0 e(1)+e(2)+e(3) -e(1)-e(2)-e(3) -e(1)-2*e(2)-3*e(4) -e(1) REXX /*REXX program displays a finite liner combination in an infinite vector basis. */@.=.; @.1 = ' 1, 2, 3 ' @.2 = ' 0, 1, 2, 3 ' @.3 = ' 1, 0, 3, 4 ' @.4 = ' 1, 2, 0 ' @.5 = ' 0, 0, 0 ' @.6 = 0 @.7 = ' 1, 1, 1 ' @.8 = ' -1, -1, -1 ' @.9 = ' -1, -2, 0, -3 ' @.10 = -1 do j=1 while @.j\==.; n= 0 /*process each vector; zero element cnt*/ y= space( translate(@.j, ,',') ) /*elide commas and superfluous blanks. */$=                                             /*nullify  output  (liner combination).*/      do k=1  for words(y);      #= word(y, k)   /* ◄───── process each of the elements.*/      if #=0  then iterate;      a= abs(# / 1)   /*if the value is zero, then ignore it.*/      s= '+ ' ;    if #<0   then s= "- "         /*define the sign:  plus(+) or minus(-)*/      n= n + 1;    if n==1  then s= strip(s)     /*if the 1st element used, remove plus.*/      if a\==1              then s= s || a'*'    /*if multiplier is unity, then ignore #*/      $=$  s'e('k")"                            /*construct a liner combination element*/      end   /*k*/   $= strip( strip($), 'L', "+")                  /*strip leading plus sign (1st element)*/  if $=='' then$= 0                            /*handle special case of no elements.  */  say right( space(@.j), 20)  ' ──► '   strip() /*align the output for presentation. */ end /*j*/ /*stick a fork in it, we're all done. */ output when using the default inputs:  1, 2, 3 ──► e(1) + 2*e(2) + 3*e(3) 0, 1, 2, 3 ──► e(2) + 2*e(3) + 3*e(4) 1, 0, 3, 4 ──► e(1) + 3*e(3) + 4*e(4) 1, 2, 0 ──► e(1) + 2*e(2) 0, 0, 0 ──► 0 0 ──► 0 1, 1, 1 ──► e(1) + e(2) + e(3) -1, -1, -1 ──► -e(1) - e(2) - e(3) -1, -2, 0, -3 ──► -e(1) - 2*e(2) - 3*e(4) -1 ──► -e(1)  Ring  # Project : Display a linear combination scalars = [[1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, -3], [-1]]for n=1 to len(scalars) str = "" for m=1 to len(scalars[n]) scalar = scalars[n] [m] if scalar != "0" if scalar = 1 str = str + "+e" + m elseif scalar = -1 str = str + "" + "-e" + m else if scalar > 0 str = str + char(43) + scalar + "*e" + m else str = str + "" + scalar + "*e" + m ok ok ok next if str = "" str = "0" ok if left(str, 1) = "+" str = right(str, len(str)-1) ok see str + nlnext  Output: e1+2*e2+3*e3 e2+2*e3+3*e4 e1+3*e3+4*e4 e1+2*e2 0 0 e1+e2+e3 -e1-e2-e3 -e1-2*e2-3*e4 -e1  Sidef Translation of: Tcl func linear_combination(coeffs) { var res = "" for e,f in (coeffs.kv) { given(f) { when (1) { res += "+e(#{e+1})" } when (-1) { res += "-e(#{e+1})" } case (.> 0) { res += "+#{f}*e(#{e+1})" } case (.< 0) { res += "#{f}*e(#{e+1})" } } } res -= /^\+/ res || 0} var tests = [ %n{1 2 3}, %n{0 1 2 3}, %n{1 0 3 4}, %n{1 2 0}, %n{0 0 0}, %n{0}, %n{1 1 1}, %n{-1 -1 -1}, %n{-1 -2 0 -3}, %n{-1},] tests.each { |t| printf("%10s -> %-10s\n", t.join(' '), linear_combination(t))} Output:  1 2 3 -> e(1)+2*e(2)+3*e(3) 0 1 2 3 -> e(2)+2*e(3)+3*e(4) 1 0 3 4 -> e(1)+3*e(3)+4*e(4) 1 2 0 -> e(1)+2*e(2) 0 0 0 -> 0 0 -> 0 1 1 1 -> e(1)+e(2)+e(3) -1 -1 -1 -> -e(1)-e(2)-e(3) -1 -2 0 -3 -> -e(1)-2*e(2)-3*e(4) -1 -> -e(1)  Tcl This solution strives for legibility rather than golf. proc lincom {factors} { set exp 0 set res "" foreach ffactors {        incr exp        if {$f == 0} { continue } elseif {$f == 1} {            append res "+e($exp)" } elseif {$f == -1} {            append res "-e($exp)" } elseif {$f > 0} {            append res "+$f*e($exp)"        } else {            append res "$f*e($exp)"        }    }    if {$res eq ""} {set res 0} regsub {^\+}$res {} res    return $res} foreach test { {1 2 3} {0 1 2 3} {1 0 3 4} {1 2 0} {0 0 0} {0} {1 1 1} {-1 -1 -1} {-1 -2 0 -3} {-1}} { puts [format "%10s -> %-10s"$test [lincom \$test]]}
Output:
     1 2 3 -> e(1)+2*e(2)+3*e(3)
0 1 2 3 -> e(2)+2*e(3)+3*e(4)
1 0 3 4 -> e(1)+3*e(3)+4*e(4)
1 2 0 -> e(1)+2*e(2)
0 0 0 -> 0
0 -> 0
1 1 1 -> e(1)+e(2)+e(3)
-1 -1 -1 -> -e(1)-e(2)-e(3)
-1 -2 0 -3 -> -e(1)-2*e(2)-3*e(4)
-1 -> -e(1)     

zkl

Translation of: Perl 6
fcn linearCombination(coeffs){   [1..].zipWith(fcn(n,c){ if(c==0) "" else "%s*e(%s)".fmt(c,n) },coeffs)      .filter().concat("+").replace("+-","-").replace("1*","")   or 0}
T(T(1,2,3),T(0,1,2,3),T(1,0,3,4),T(1,2,0),T(0,0,0),T(0),T(1,1,1),T(-1,-1,-1),  T(-1,-2,0,-3),T(-1),T).pump(Console.println,linearCombination);
Output:
e(1)+2*e(2)+3*e(3)
e(2)+2*e(3)+3*e(4)
e(1)+3*e(3)+4*e(4)
e(1)+2*e(2)
0
0
e(1)+e(2)+e(3)
-e(1)-e(2)-e(3)
-e(1)-2*e(2)-3*e(4)
-e(1)
0