Display a linear combination
Display a finite linear combination in an infinite vector basis .
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Write a function that, when given a finite list of scalars ,
creates a string representing the linear combination in an explicit format often used in mathematics, that is:
where
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
11l
<lang 11l>F linear(x)
V a = enumerate(x).filter2((i, v) -> v != 0).map2((i, v) -> ‘#.e(#.)’.format(I v == -1 {‘-’} E I v == 1 {‘’} E String(v)‘*’, i + 1)) R (I !a.empty {a} E [String(‘0’)]).join(‘ + ’).replace(‘ + -’, ‘ - ’)
L(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]]
print(linear(x))</lang>
- 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)
Ada
<lang Ada>with Ada.Text_Io; with Ada.Strings.Unbounded; with Ada.Strings.Fixed;
procedure Display_Linear is
subtype Position is Positive; type Coefficient is new Integer; type Combination is array (Position range <>) of Coefficient;
function Linear_Combination (Comb : Combination) return String is use Ada.Strings.Unbounded; use Ada.Strings; Accu : Unbounded_String; begin for Pos in Comb'Range loop case Comb (Pos) is when Coefficient'First .. -1 => Append (Accu, (if Accu = "" then "-" else " - ")); when 0 => null; when 1 .. Coefficient'Last => Append (Accu, (if Accu /= "" then " + " else "")); end case;
if Comb (Pos) /= 0 then declare Abs_Coeff : constant Coefficient := abs Comb (Pos); Coeff_Image : constant String := Fixed.Trim (Coefficient'Image (Abs_Coeff), Left); Exp_Image : constant String := Fixed.Trim (Position'Image (Pos), Left); begin if Abs_Coeff /= 1 then Append (Accu, Coeff_Image & "*"); end if; Append (Accu, "e(" & Exp_Image & ")"); end; end if; end loop;
return (if Accu = "" then "0" else To_String (Accu)); end Linear_Combination;
use Ada.Text_Io;
begin
Put_Line (Linear_Combination ((1, 2, 3))); Put_Line (Linear_Combination ((0, 1, 2, 3))); Put_Line (Linear_Combination ((1, 0, 3, 4))); Put_Line (Linear_Combination ((1, 2, 0))); Put_Line (Linear_Combination ((0, 0, 0))); Put_Line (Linear_Combination ((1 => 0))); Put_Line (Linear_Combination ((1, 1, 1))); Put_Line (Linear_Combination ((-1, -1, -1))); Put_Line (Linear_Combination ((-1, -2, 0, -3))); Put_Line (Linear_Combination ((1 => -1)));
end Display_Linear;</lang>
- 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)
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. <lang C>
- 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; } </lang>
- 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
C#
<lang csharp>using System; using System.Collections.Generic; using System.Text;
namespace DisplayLinearCombination {
class Program { static string LinearCombo(List<int> c) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < c.Count; i++) { int n = c[i]; if (n < 0) { if (sb.Length == 0) { sb.Append('-'); } else { sb.Append(" - "); } } else if (n > 0) { if (sb.Length != 0) { sb.Append(" + "); } } else { continue; }
int av = Math.Abs(n); if (av != 1) { sb.AppendFormat("{0}*", av); } sb.AppendFormat("e({0})", i + 1); } if (sb.Length == 0) { sb.Append('0'); } return sb.ToString(); }
static void Main(string[] args) { List<List<int>> combos = new List<List<int>>{ new List<int> { 1, 2, 3}, new List<int> { 0, 1, 2, 3}, new List<int> { 1, 0, 3, 4}, new List<int> { 1, 2, 0}, new List<int> { 0, 0, 0}, new List<int> { 0}, new List<int> { 1, 1, 1}, new List<int> { -1, -1, -1}, new List<int> { -1, -2, 0, -3}, new List<int> { -1}, };
foreach (List<int> c in combos) { var arr = "[" + string.Join(", ", c) + "]"; Console.WriteLine("{0,15} -> {1}", arr, LinearCombo(c)); } } }
}</lang>
- 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)
C++
<lang cpp>#include <iomanip>
- include <iostream>
- include <sstream>
- include <vector>
template<typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
auto it = v.cbegin(); auto end = v.cend();
os << '['; if (it != end) { os << *it; it = std::next(it); } while (it != end) { os << ", " << *it; it = std::next(it); } return os << ']';
}
std::ostream& operator<<(std::ostream& os, const std::string& s) {
return os << s.c_str();
}
std::string linearCombo(const std::vector<int>& c) {
std::stringstream ss; for (size_t i = 0; i < c.size(); i++) { int n = c[i]; if (n < 0) { if (ss.tellp() == 0) { ss << '-'; } else { ss << " - "; } } else if (n > 0) { if (ss.tellp() != 0) { ss << " + "; } } else { continue; }
int av = abs(n); if (av != 1) { ss << av << '*'; } ss << "e(" << i + 1 << ')'; } if (ss.tellp() == 0) { return "0"; } return ss.str();
}
int main() {
using namespace std;
vector<vector<int>> 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}, };
for (auto& c : combos) { stringstream ss; ss << c; cout << setw(15) << ss.str() << " -> "; cout << linearCombo(c) << '\n'; }
return 0;
}</lang>
- 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)
D
<lang D>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)); }
}</lang>
- 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
<lang scheme>
- 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%d " plus i)) ((= a -1) (format "- e%d " i)) ((> a 0) (format "%a %d*e%d " plus a i)) ((< a 0) (format "- %d*e%d " (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 -> %a
" linear (linear->html linear)))))
</lang>
- 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
<lang elixir>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 end
end
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))</lang>
- 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
<lang fsharp> // Display a linear combination. Nigel Galloway: March 28th., 2018 let 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
</lang>
The Task
<lang fsharp> fN [1;2;3] </lang>
- Output:
e(1)+2e(2)+3e(3)
<lang fsharp> fN [0;1;2;3] </lang>
- Output:
e(2)+2e(3)+3e(4)
<lang fsharp> fN[1;0;3;4] </lang>
- Output:
e(1)+3e(3)+4e(4)
<lang fsharp> fN[1;2;0] </lang>
- Output:
e(1)+2e(2)
<lang fsharp> fN[0;0;0] </lang>
- Output:
0
<lang fsharp> fN[0] </lang>
- Output:
0
<lang fsharp> fN[1;1;1] </lang>
- Output:
e(1)+e(2)+e(3)
<lang fsharp> fN[-1;-1;-1] </lang>
- Output:
-e(1)-e(2)-e(3)
<lang fsharp> fN[-1;-2;0;-3] </lang>
- Output:
-e(1)-2e(2)-3e(4)
<lang fsharp> fN[1] </lang>
- Output:
e(1)
Factor
<lang 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</lang>
- 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)
FreeBASIC
<lang freebasic>Dim scalars(1 To 10, 1 To 4) As Integer => {{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 As Integer = 1 To Ubound(scalars)
Dim As String cadena = "" Dim As Integer scalar For m As Integer = 1 To Ubound(scalars,2) scalar = scalars(n, m) If scalar <> 0 Then If scalar = 1 Then cadena &= "+e" & m Elseif scalar = -1 Then cadena &= "-e" & m Else If scalar > 0 Then cadena &= Chr(43) & scalar & "*e" & m Else cadena &= scalar & "*e" & m End If End If End If Next m If cadena = "" Then cadena = "0" If Left(cadena, 1) = "+" Then cadena = Right(cadena, Len(cadena)-1) Print cadena
Next n Sleep</lang>
- Output:
Igual que la entrada de Ring.
Go
<lang go>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)) }
}</lang>
- 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)
Groovy
<lang groovy>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() }
static void main(String[] args) { int[][] 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] ]
for (int[] c : combos) { printf("%-15s -> %s\n", Arrays.toString(c), linearCombo(c)) } }
}</lang>
- 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)
Haskell
<lang haskell>import Text.Printf (printf)
linearForm :: [Int] -> String linearForm = strip . concat . zipWith term [1..]
where term :: Int -> Int -> String term i c = case c of 0 -> mempty 1 -> printf "+e(%d)" i -1 -> printf "-e(%d)" i c -> printf "%+d*e(%d)" c i
strip str = case str of '+':s -> s "" -> "0" s -> s</lang>
Testing
<lang haskell>coeffs :: Int 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] ]</lang>
λ> mapM_ (print . linearForm) coeffs "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)"
J
Implementation:
<lang J>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.
)</lang>
Example use:
<lang J> fourbanger 1 2 3 e(1)+2*e(2)+3*e(3)
fourbanger 0 1 2 3
e(2)+2*e(3)+3*e(4)
fourbanger 1 0 3 4
e(1)+3*e(3)+4*e(4)
fourbanger 0 0 0
0
fourbanger 0
0
fourbanger 1 1 1
e(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)</lang>
Java
<lang Java>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)); } }
}</lang>
- 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)
jq
<lang jq>def linearCombo:
reduce to_entries[] as {key: $k,value: $v} (""; if $v == 0 then . else (if $v < 0 and length==0 then "-" elif $v < 0 then " - " elif $v > 0 and length==0 then "" else " + " end) as $sign | ($v|fabs) as $av | (if ($av == 1) then "" else "\($av)*" end) as $coeff | . + "\($sign)\($coeff)e\($k)" end) | if length==0 then "0" else . end ;
- The exercise
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
[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] | "\(lpad(15)) => \(linearCombo)" </lang>
- Output:
<lang sh> [1,2,3] => e0 + 2*e1 + 3*e2
[0,1,2,3] => e1 + 2*e2 + 3*e3 [1,0,3,4] => e0 + 3*e2 + 4*e3 [1,2,0] => e0 + 2*e1 [0,0,0] => 0 [0] => 0 [1,1,1] => e0 + e1 + e2 [-1,-1,-1] => -e0 - e1 - e2 [-1,-2,0,-3] => -e0 - 2*e1 - 3*e3 [-1] => -e0</lang>
Julia
<lang 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</lang>
- 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
<lang scala>// 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)}") }
}</lang>
- 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)
Lambdatalk
<lang scheme>
{def linearcomb
{def linearcomb.r {lambda {:a :n :i} {if {= :i :n} then else {let { {:e e({+ :i 1})} {:v {abs {A.get :i :a}}} {:s {if {< {A.get :i :a} 0} then - else +}} } {if {= :v 0} then else {if {= :v 1} then :s :e else :s :v*:e}}} {linearcomb.r :a :n {+ :i 1}} }}} {lambda {:a} {S.replace _LAMB_[^\s]+ by 0 in {let { {:r {linearcomb.r {A.new :a} {S.length :a} 0}} } {if {W.equal? {S.first :r} +} then {S.rest :r} else :r} }}}}
-> linearcomb
{linearcomb 1 2 3} -> e(1) + 2*e(2) + 3*e(3) {linearcomb -1 -2 0 -3} -> - e(1) - 2*e(2) - 3*e(4) {linearcomb 0 1 2 3} -> e(2) + 2*e(3) + 3*e(4) {linearcomb 1 0 3 4} -> e(1) + 3*e(3) + 4*e(4) {linearcomb 1 2 0} -> e(1) + 2*e(2) {linearcomb 0 0 0} -> 0 {linearcomb 0} -> 0 {linearcomb 1 1 1} -> e(1) + e(2) + e(3) {linearcomb -1 -1 -1} -> - e(1) - e(2) - e(3) {linearcomb -1} -> - e(1)
</lang>
Lua
<lang lua>function t2s(t)
local s = "[" for i,v in pairs(t) do if i > 1 then s = s .. ", " .. v else s = s .. v end end return s .. "]"
end
function linearCombo(c)
local sb = "" for i,n in pairs(c) do local skip = false
if n < 0 then if sb:len() == 0 then sb = sb .. "-" else sb = sb .. " - " end elseif n > 0 then if sb:len() ~= 0 then sb = sb .. " + " end else skip = true end
if not skip then local av = math.abs(n) if av ~= 1 then sb = sb .. av .. "*" end sb = sb .. "e(" .. i .. ")" end end if sb:len() == 0 then sb = "0" end return sb
end
function main()
local 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 } }
for i,c in pairs(combos) do local arr = t2s(c) print(string.format("%15s -> %s", arr, linearCombo(c))) end
end
main()</lang>
- 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)
Mathematica / Wolfram Language
<lang Mathematica>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}}; Column[TraditionalForm[Total[MapIndexed[#1 e[#21] &, #]]] & /@ tests]</lang>
- Output:
e(1)+2e(2)+3e(3) e(2)+2e(3)+3e(4) e(1)+3e(3)+4e(4) e(1)+2e(2) 0 0 e(1)+e(2)+e(3) -e(1)-e(2)-e(3) -e(1)-2e(2)-3e(4) -e(1)
Modula-2
<lang modula2>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; WriteLn
END 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});
ReadChar
END Linear.</lang>
Nim
<lang Nim>import strformat
proc linearCombo(c: openArray[int]): string =
for i, n in c: if n == 0: continue let op = if n < 0: if result.len == 0: "-" else: " - " else: if n > 0 and result.len == 0: "" else: " + " let av = abs(n) let coeff = if av == 1: "" else: $av & '*' result &= fmt"{op}{coeff}e({i + 1})" if result.len == 0: result = "0"
const 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]]
for c in Combos:
echo fmt"{($c)[1..^1]:15} → {linearCombo(c)}"</lang>
- 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)
Perl
<lang perl>use strict; use warnings; use feature 'say';
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 or 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 ]</lang>
- 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
with javascript_semantics 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 res end 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)
PureBasic
<lang PureBasic>; Process and output values. Procedure WriteLinear(Array c.i(1))
Define buf$, i.i, j.i, b,i b = #True j = 0 For i = 0 To ArraySize(c(), 1) If c(i) = 0 : Continue : EndIf If c(i) < 0 If b : Print("-") : Else : Print(" - ") : EndIf ElseIf c(i) > 0 If Not b : Print(" + ") : EndIf EndIf If c(i) > 1 Print(Str(c(i))+"*") ElseIf c(i) < -1 Print(Str(-c(i))+"*") EndIf Print("e("+Str(i+1)+")") b = #False j+1 Next If j = 0 : Print("0") : EndIf PrintN("")
EndProcedure
Macro VectorHdl(Adr_Start, Adr_Stop)
; 1. Output of the input values Define buf$ = "[", *adr_ptr For *adr_ptr = Adr_Start To Adr_Stop - SizeOf(Integer) Step SizeOf(Integer) buf$ + Str(PeekI(*adr_ptr)) If *adr_ptr >= Adr_Stop - SizeOf(Integer) buf$ + "] -> " Else buf$ + ", " EndIf Next buf$ = RSet(buf$, 25) Print(buf$) ; 2. Reserve memory, pass and process values. Dim a.i((Adr_Stop - Adr_Start) / SizeOf(Integer) -1) CopyMemory(Adr_Start, @a(0), Adr_Stop - Adr_Start) WriteLinear(a())
EndMacro
If OpenConsole("")
; Pass memory addresses of the data. VectorHdl(?V1, ?_V1) VectorHdl(?V2, ?_V2) VectorHdl(?V3, ?_V3) VectorHdl(?V4, ?_V4) VectorHdl(?V5, ?_V5) VectorHdl(?V6, ?_V6) VectorHdl(?V7, ?_V7) VectorHdl(?V8, ?_V8) VectorHdl(?V9, ?_V9) VectorHdl(?V10, ?_V10) Input()
EndIf
End 0
DataSection
V1: Data.i 1,2,3 _V1: V2: Data.i 0,1,2,3 _V2: V3: Data.i 1,0,3,4 _V3: V4: Data.i 1,2,0 _V4: V5: Data.i 0,0,0 _V5: V6: Data.i 0 _V6: V7: Data.i 1,1,1 _V7: V8: Data.i -1,-1,-1 _V8: V9: Data.i -1,-2,0,-3 _V9: V10: Data.i -1 _V10:
EndDataSection</lang>
- 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
<lang 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]]))
</lang>
- 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>#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)))
</lang>
- 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)
Raku
(formerly Perl 6) <lang perl6>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 ]
- </lang>
- 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
<lang rexx>/*REXX program displays a finite liner combination in an infinite vector basis. */ @.= .; @.1 = ' 1, 2, 3 ' /*define a specific test case for build*/
@.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.*/ if #<0 then s= '- ' /*define the sign: minus (-). */ else s= '+ ' /* " " " plus (+). */ n= n + 1 /*bump the number of elements in vector*/ if n==1 then s= strip(s) /*if the 1st element used, remove blank*/ 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. */</lang>
- 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
<lang 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 + nl
next </lang> 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
Ruby
<lang ruby>def linearCombo(c)
sb = "" c.each_with_index { |n, i| if n == 0 then next end if n < 0 then if sb.length == 0 then op = "-" else op = " - " end elsif n > 0 then if sb.length > 0 then op = " + " else op = "" end else op = "" end av = n.abs() if av != 1 then coeff = "%d*" % [av] else coeff = "" end sb = sb + "%s%se(%d)" % [op, coeff, i + 1] } if sb.length == 0 then return "0" end return sb
end
def main
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], ]
for c in combos do print "%-15s -> %s\n" % [c, linearCombo(c)] end
end
main()</lang>
- 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)
Rust
<lang rust> use std::fmt::{Display, Formatter, Result}; use std::process::exit;
struct Coefficient(usize, f64);
impl Display for Coefficient {
fn fmt(&self, f: &mut Formatter<'_>) -> Result { let i = self.0; let c = self.1;
if c == 0. { return Ok(()); }
write!( f, " {} {}e({})", if c < 0. { "-" } else if f.alternate() { " " } else { "+" }, if (c.abs() - 1.).abs() < f64::EPSILON { "".to_string() } else { c.abs().to_string() + "*" }, i + 1 ) }
}
fn usage() {
println!("Usage: display-linear-combination a1 [a2 a3 ...]");
}
fn linear_combination(coefficients: &[f64]) -> String {
let mut string = String::new();
let mut iter = coefficients.iter().enumerate();
// find first nonzero argument loop { match iter.next() { Some((_, &c)) if c == 0. => { continue; } Some((i, &c)) => { string.push_str(format!("{:#}", Coefficient(i, c)).as_str()); break; } None => { string.push('0'); return string; } } }
// print subsequent arguments for (i, &c) in iter { string.push_str(format!("{}", Coefficient(i, c)).as_str()); }
string
}
fn main() {
let mut coefficients = Vec::new(); let mut args = std::env::args();
args.next(); // drop first argument
// parse arguments into floats for arg in args { let c = arg.parse::<f64>().unwrap_or_else(|e| { eprintln!("Failed to parse argument \"{}\": {}", arg, e); exit(-1); }); coefficients.push(c); }
// no arguments, print usage and exit if coefficients.is_empty() { usage(); return; }
println!("{}", linear_combination(&coefficients));
} </lang>
- Output:
1 2 3 -> e(1) + 2*e(2) + 3*e(3)
Scala
<lang Scala>object LinearCombination extends App {
val combos = Seq(Seq(1, 2, 3), Seq(0, 1, 2, 3), Seq(1, 0, 3, 4), Seq(1, 2, 0), Seq(0, 0, 0), Seq(0), Seq(1, 1, 1), Seq(-1, -1, -1), Seq(-1, -2, 0, -3), Seq(-1))
private def linearCombo(c: Seq[Int]): String = { val sb = new StringBuilder for {i <- c.indices term = c(i) if term != 0} { val av = math.abs(term) def op = if (term < 0 && sb.isEmpty) "-" else if (term < 0) " - " else if (term > 0 && sb.isEmpty) "" else " + "
sb.append(op).append(if (av == 1) "" else s"$av*").append("e(").append(i + 1).append(')') } if (sb.isEmpty) "0" else sb.toString } for (c <- combos) { println(f"${c.mkString("[", ", ", "]")}%-15s -> ${linearCombo(c)}%s") }
}</lang>
Sidef
<lang ruby>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))
}</lang>
- 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.
<lang Tcl>proc lincom {factors} {
set exp 0 set res "" foreach f $factors { 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]]
}</lang>
- 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)
Visual Basic .NET
<lang vbnet>Imports System.Text
Module Module1
Function LinearCombo(c As List(Of Integer)) As String Dim sb As New StringBuilder For i = 0 To c.Count - 1 Dim n = c(i) If n < 0 Then If sb.Length = 0 Then sb.Append("-") Else sb.Append(" - ") End If ElseIf n > 0 Then If sb.Length <> 0 Then sb.Append(" + ") End If Else Continue For End If
Dim av = Math.Abs(n) If av <> 1 Then sb.AppendFormat("{0}*", av) End If sb.AppendFormat("e({0})", i + 1) Next If sb.Length = 0 Then sb.Append("0") End If Return sb.ToString() End Function
Sub Main() Dim combos = New List(Of List(Of Integer)) From { New List(Of Integer) From {1, 2, 3}, New List(Of Integer) From {0, 1, 2, 3}, New List(Of Integer) From {1, 0, 3, 4}, New List(Of Integer) From {1, 2, 0}, New List(Of Integer) From {0, 0, 0}, New List(Of Integer) From {0}, New List(Of Integer) From {1, 1, 1}, New List(Of Integer) From {-1, -1, -1}, New List(Of Integer) From {-1, -2, 0, -3}, New List(Of Integer) From {-1} }
For Each c In combos Dim arr = "[" + String.Join(", ", c) + "]" Console.WriteLine("{0,15} -> {1}", arr, LinearCombo(c)) Next End Sub
End Module</lang>
- 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)
Wren
<lang ecmascript>import "/fmt" for Fmt
var linearCombo = Fn.new { |c|
var sb = "" var i = 0 for (n in c) { if (n != 0) { var op = (n < 0 && sb == "") ? "-" : (n < 0) ? " - " : (n > 0 && sb == "") ? "" : " + " var av = n.abs var coeff = (av == 1) ? "" : "%(av)*" sb = sb + "%(op)%(coeff)e(%(i + 1))" } i = i + 1 } return (sb == "") ? "0" : sb
}
var 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]
] for (c in combos) {
Fmt.print("$-15s -> $s", c.toString, linearCombo.call(c))
}</lang>
- 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
<lang zkl>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
}</lang> <lang zkl>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);</lang>
- 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